def set_prefs(prefs):
    """This function is called before opening the project"""
    prefs['ignored_resources'] = ['*.pyc', '*~', '.ropeproject', '.hg',
        '.svn', '_svn', '.git', '.tox', '.env', 'env', 'venv',
        'node_modules', 'bower_components']
    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'


@classmethod
def attach(cls, template, stream, value, namespaces, pos):
    """Called after the template stream has been completely parsed.

        :param template: the `Template` object
        :param stream: the event stream associated with the directive
        :param value: the argument value for the directive; if the directive was
                      specified as an element, this will be an `Attrs` instance
                      with all specified attributes, otherwise it will be a
                      `unicode` object with just the attribute value
        :param namespaces: a mapping of namespace URIs to prefixes
        :param pos: a ``(filename, lineno, offset)`` tuple describing the
                    location where the directive was found in the source

        This class method should return a ``(directive, stream)`` tuple. If
        ``directive`` is not ``None``, it should be an instance of the `Directive`
        class, and gets added to the list of directives applied to the substream
        at runtime. `stream` is an event stream that replaces the original
        stream associated with the directive.
        """
    return cls(value, template, namespaces, *pos[1:]), stream


@staticmethod
def _get_parent_dn(dn):
    """
        Gets the dn of the parent object
        Meant to be overridden by inheriting classes.
        Raises exception if not overridden.

        :returns: string containing dn
        """
    return dn.split('/sys/ctx-')[0]


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


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

        :param ChangedEnterpriseConnectedTeamStatusDetails val:
        :rtype: EventDetails
        """
    return cls('changed_enterprise_connected_team_status_details', val)


def truncate(name, text):
    """Truncate the text. The filter will remove any external data
        associated to the named text (references, code sources).
        """


def read_genes(fname, descriptions=False):
    """
      (Filename, Options) -> [Gene]
      Gene :: {start, end, rv, gene, strand}
    """
    genes = []
    for line in open(fname):
        w = line.rstrip().split('\t')
        data = {'start': int(w[1]), 'end': int(w[2]), 'rv': w[8], 'gene': w
            [7], 'strand': w[3]}
        if descriptions == True:
            data.append(w[0])
        genes.append(data)
    return genes


def forward_kinematics(acceleration, velocity_0, angle_0, delta_time):
    """Compute the forward kinematics with finite difference method."""
    velocity_1 = velocity_0 + acceleration * delta_time
    angle_1 = angle_0 + velocity_1 * delta_time
    return velocity_1, angle_1


def apply_styles(graph, styles):
    """ Apply styles to graph

    Note:
        Also have a look at :class:`smalisca.core.GraphConfig`

    Args:
        graph (Graph): Graph to apply styles to
        styles (dict): List of styles

    Returns:
        Graph: Return modified Graph

    Examples:

        # Define styles
        graph_styles = {
            'graph': {
                'rankdir': 'LR',
                'splines': 'ortho',
                'bgcolor': 'black'
            },
            'nodes': {
                'shape': 'record',
                'color': 'orange',
                'fontcolor': 'orange',
                'style': 'filled',
                'fillcolor': '#1c1c1c'
            },
            'edges': {
                'color': 'orange'
            }
        }

        # Apply styles
        apply_styles(myGraph, graph_styles)

    """
    graph.graph_attr.update('graph' in styles and styles['graph'] or {})
    graph.node_attr.update('nodes' in styles and styles['nodes'] or {})
    graph.edge_attr.update('edges' in styles and styles['edges'] or {})


def _is_empty(mime_type):
    """
    Return whether a template file is an empty file.
    """
    return mime_type == 'inode/x-empty'


def add_artifact_path(parser):
    """Add an `artifact-path` flag to _parser_."""
    parser.add_argument('--artifact-path', help=
        'Local path to artifact directory for S3 deployments')


@classmethod
def add_to_hd_component_temperature(cls, session, target, temp_change, limit):
    """Add to cv temperature sensor value
        Args:
            session:  database session
            target(dict): target attributes such as key of the server, controller & serial number
            temp_change(int): value to be added to the target temperature
            limit(dict): indicates that target temp cannot go beyond this limit (upper & lower)
        Returns:
            tuple: True if the temp value was updated & current temp value (updated)
        """
    query = []
    query.extend([
        'MATCH (:Asset {{ key: {} }})-[:HAS_CONTROLLER]->(ctrl:Controller {{ controllerNum: {} }})'
        .format(target['server_key'], target['controller']),
        'MATCH (ctr)-[:HAS_CACHEVAULT|:HAS_PHYSICAL_DRIVE]->(hd_element:{} {{ {}: {} }})'
        .format(target['hd_type'], target['attribute'], target['value']),
        'RETURN hd_element.temperature as temp'])
    results = session.run('\n'.join(query))
    record = results.single()
    current_temp = record.get('temp')
    new_temp = current_temp + temp_change
    new_temp = max(new_temp, limit['lower'])
    if 'upper' in limit and limit['upper']:
        new_temp = min(new_temp, limit['upper'])
    if new_temp == current_temp:
        return False, current_temp
    query = query[:2]
    query.append('SET hd_element.temperature={}'.format(new_temp))
    session.run('\n'.join(query))
    return True, new_temp


def import_messages(file):
    """ Import messages into mailing list archive """


def calculate_metabolic_coverage(model):
    u"""
    Return the ratio of reactions and genes included in the model.

    Determine whether the amount of reactions and genes in model not equal to
    zero, then return the ratio.

    Parameters
    ----------
    model : cobra.Model
        The metabolic model under investigation.

    Returns
    -------
    float
        The ratio of reactions to genes also called metabolic coverage.

    Raises
    ------
    ValueError
        If the model does not contain either reactions or genes.

    Notes
    -----
    According to [1]_ this is a good quality indicator expressing the degree of
    metabolic coverage i.e. modeling detail of a given reconstruction. The
    authors explain that models with a 'high level of modeling detail have
    ratios >1, and [models] with low level of detail have ratios <1'. They
    explain that 'this difference arises because [models] with basic or
    intermediate levels of detail often include many reactions in which several
    gene products and their enzymatic transformations are ‘lumped’'.

    References
    ----------
    .. [1] Monk, J., Nogales, J., & Palsson, B. O. (2014). Optimizing
          genome-scale network reconstructions. Nature Biotechnology, 32(5),
          447–452. http://doi.org/10.1038/nbt.2870

    """
    if len(model.reactions) == 0 or len(model.genes) == 0:
        raise ValueError('The model contains no reactions or genes.')
    return float(len(model.reactions)) / float(len(model.genes))


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


@staticmethod
def dtype(x):
    """Option to enforce a Homogeneous datatype."""
    return x


def dbh_xlg_limatix(path, contenttype, extension, roottag, nsurl):
    """ Generic XLG Handler - Returns xlg_viewer for all XLG files """
    if (extension == 'xlg' or extension == 'xlp') and nsurl.startswith(
        'http://limatix.org'):
        return 'db_limatix_viewer'
    else:
        return False


def read(filename):
    """Read filename and return its contents as a long string"""
    import codecs
    with codecs.open(filename, 'r') as f:
        data = f.read()
    return data


def improve_reportstr_readibilty(src):
    """
        improve_reportstr_readibilty()
        ________________________________________________________________________

        Improve the readibilty of the (str)src so that this string may be
        easily read in a report.
        ________________________________________________________________________

        ARGUMENT:
        ▪ src   : (str) the string to be returned, slightly modified

        RETURNED VALUE : the expected (str)string.
    """
    src = src.replace(' ', '_')
    return src


def _convert_randomuniformlike(builder, node, graph, err):
    """
    convert to CoreML Random Normal Like Layer:
    https://github.com/apple/coremltools/blob/655b3be5cc0d42c3c4fa49f0f0e4a93a26b3e492/mlmodel/format/NeuralNetwork.proto#L4503
    """
    mean = node.attributes.get('mean', 0.0)
    scale = node.attributes.get('scale', 1.0)
    seed = node.attributes.get('seed', -1)
    builder.add_random_uniform_like(name=node.name, input_name=node.inputs[
        0], output_name=node.outputs[0], mean=mean, stddev=scale, seed=seed)


def vdowham(eta, vel_entrain, e_eff, r_eff):
    """

    Calculate the velocity parameter of the contact problem according to
    Dowson-Hamrock.

    Parameters
    ----------
    eta: ndarray, scalar
        The dynamic viscosity of the lubricant.
    vel_entrain: ndarray, scalar
        The entrainment velocity of the contact problem.
    e_eff: ndarray, scalar
        The effective modulus of the contact problem.
    r_eff: ndarray, scalar
        The effective radius of the contact problem.

    Returns
    -------
    param_velocity: ndarray, scalar
        The velocity parameter of the contact problem.

    """
    param_velocity = eta * vel_entrain / (e_eff * r_eff)
    return param_velocity


def cols_to_int(df, columns):
    """Convert selected column values to int and return dataframe.

    Args:
        df: Pandas dataframe.
        columns: List of columns to convert.

    Returns:
        Original dataframe with converted column data.
    """
    for col in columns:
        df[col] = df[col].astype(int)
    return df


@staticmethod
def isDocstring():
    """True if it is a docstring"""
    return False


def isRootLink(link, childList):
    """Check if a link is root link."""
    for child in childList:
        if link == child:
            return False
    return True


def google_has_height(style):
    """check if the style of the element has the 'height' attribute explicitly defined"""
    if 'height' in style:
        return True
    return False


def contour_plotter(axis, snr_vals, contours, colors, vert_spike=False):
    """Plot contours in a scatter plot where SNR is on the horizontal axis"""
    for i, _ in enumerate(contours):
        plot_vals_x = []
        plot_vals_y = []
        if vert_spike:
            for j, _ in enumerate(snr_vals):
                if contours[i][j] > 1e-15 and not plot_vals_x:
                    plot_vals_x.append(snr_vals[j])
                    plot_vals_y.append(0.1)
                if contours[i][j] > 1e-15 and plot_vals_x:
                    plot_vals_x.append(snr_vals[j])
                    plot_vals_y.append(contours[i][j])
        else:
            plot_vals_x = snr_vals
            plot_vals_y = contours[i]
        axis.plot(plot_vals_x, plot_vals_y, colors[i])


def write_boolean(encoder, datum, schema=None):
    """A boolean is written as a single byte whose value is either 0 (false) or
    1 (true)."""
    encoder.write_boolean(datum)


def find_duplicate_schedule_items(all_items):
    """Find talks / pages assigned to mulitple schedule items"""
    duplicates = []
    seen_talks = {}
    for item in all_items:
        if item.talk and item.talk in seen_talks:
            duplicates.append(item)
            if seen_talks[item.talk] not in duplicates:
                duplicates.append(seen_talks[item.talk])
        else:
            seen_talks[item.talk] = item
    return duplicates


def deduplicate_left_right_realisation(left_word, right_word):
    """Remove the right word realisation if it's a duplicate of the left one."""
    if left_word.realisation == 'de' and right_word.realisation in ['de',
        'du', "d'"
        ] or left_word.realisation == 'que' and right_word.realisation in [
        'que', "qu'"]:
        right_word.realisation = None
        return True


@classmethod
def from_lva(cls, lva, owner):
    """
        Loads address translator with LVA
        """
    return cls(lva - owner.linked_base, owner)


def compute_out_dims(in_dims, kernel_size, stride, padding, output_padding,
    dilation):
    """Computes the output dimensions of convolution.

  The formulas below are based on what Keras does.

  Args:
    in_dims: number of input dimensions.
    kernel_size: size of kernel.
    stride: size of stride.
    padding: amount of padding on both ends of input.
    output_padding: padding adjustment for disambiguating out_dims.
    dilation: amount of dilation for convolution.

  Returns:
    The computed value of output dimensions.
  """
    kernel_size = (kernel_size - 1) * dilation + 1
    if output_padding is None:
        if padding == 'same':
            out_dims = in_dims * stride
        elif padding == 'valid':
            out_dims = in_dims * stride + max(kernel_size - stride, 0)
    elif padding == 'same':
        out_dims = (in_dims - 1) * stride + output_padding
    elif padding == 'valid':
        out_dims = (in_dims - 1) * stride + kernel_size + output_padding
    return out_dims


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

        :param SharedLinkSettingsAllowDownloadDisabledType val:
        :rtype: EventType
        """
    return cls('shared_link_settings_allow_download_disabled', val)


def get_job_metrics(job):
    """
    Return a properly formatted job metrics string.
    The format of the job metrics string is defined by the server. It will be reported to the server during updateJob.

    Example of job metrics:
    Number of events read | Number of events written | vmPeak maximum | vmPeak average | RSS average | ..
    Format: nEvents=<int> nEventsW=<int> vmPeakMax=<int> vmPeakMean=<int> RSSMean=<int> hs06=<float> shutdownTime=<int>
            cpuFactor=<float> cpuLimit=<float> diskLimit=<float> jobStart=<int> memLimit=<int> runLimit=<float>

    :param job: job object.
    :return: job metrics (string).
    """
    return ''


def _reset_dmats(shape_dmats, indices):
    """Set values in dmats equal to the identity matrix."""
    f_assign = format['assign']
    f_float = format['floating point']
    i, j = indices
    code = [format['comment'](
        'Resetting dmats values to compute next derivative.')]
    dmats_old = format['component'](format['dmats'](''), [i, j])
    lines = [f_assign(dmats_old, f_float(0.0))]
    lines += [format['if'](i + format['is equal'] + j, f_assign(dmats_old,
        f_float(1.0)))]
    loop_vars = [(i, 0, shape_dmats[0]), (j, 0, shape_dmats[1])]
    code += format['generate loop'](lines, loop_vars)
    return code


@classmethod
def info(cls, id):
    """ Display information about a hosted certificate. """
    return cls.call('cert.hosted.info', id)


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

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

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


def wrap_func_like_safe(func, func_like, *args, **kwargs):
    """
    Safe implementation for wrap_func_like(), attempts to use func_like(),
    if the shape keyword argument, falls back to func().
    """
    try:
        return func_like(*args, **kwargs)
    except TypeError:
        return func(*args, **kwargs)


def p_multiple_encapsed(p):
    """multiple_encapsed : multiple_encapsed ENCAPSED_AND_WHITESPACE
                         | empty"""
    if len(p) == 3:
        p[0] = p[1] + p[2]
    else:
        p[0] = ''


def format_list(extracted_list):
    """
    Format a list of traceback entry tuples.
    """
    list = []
    for _, filename, lineno, func_name, line, _ in extracted_list:
        code = ''.join(line).strip()
        item = 'File "%s", line %d, in %s\n  %s\n' % (filename, lineno,
            func_name, code)
        list.append(item)
    return list


def factorise(number: int):
    """Factorise a number to avoid too large a downsample factor

    Parameters
    ----------
    number : int
        The number to factorise

    Returns
    -------
    List[int]
        The downsampling factors to use

    Notes
    -----
    There's a few pathological cases here that are being ignored. For example, what if the downsample factor is the product of two primes greater than 13.
    """
    import primefac
    factors = list(primefac.primefac(number))
    downsamples = []
    val = 1
    for f in factors:
        test = val * f
        if test > 13:
            downsamples.append(val)
            val = 1
        val = val * f
    downsamples.append(val)
    return downsamples


def super_class(cls):
    """Return the next class in the MRO of cls, or object."""
    mro = cls.__mro__
    assert len(mro) > 0
    if len(mro) == 1:
        assert mro[0] is object
        return object
    return mro[1]


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 mario():
    """
Displays a nice Super Mario. :)

Analogous to \\mario in LaTeX.
	"""
    from IPython.display import Image
    from IPython.core.display import HTML
    Image(url=
        'https://banner2.kisspng.com/20180410/kye/kisspng-new-super-mario-bros-u-super-mario-64-8-bit-5acd5c8ba05651.6908995015234080116568.jpg'
        )


def _get_switch_str(opt):
    """
    Output just the '-r, --rev [VAL]' part of the option string.
    """
    if opt[2] is None or opt[2] is True or opt[2] is False:
        default = ''
    else:
        default = '[VAL]'
    if opt[0]:
        return '-%s, --%s %s' % (opt[0], opt[1], default)
    else:
        return '--%s %s' % (opt[1], default)


def site_enabled():
    """
        If syndication is enabled on the site
        """


def setLastAccessTime():
    """
        An API for `ISessionDataContainer` to set the last retrieved epoch
        time.
        """


@classmethod
def convert(cls, value, from_unit, to_unit):
    """Convert a value from one time unit to another.

        :return: the numeric value converted to the desired unit
        :rtype: float
        """
    value_ms = value * cls.UNITS_IN_MILLISECONDS[from_unit]
    return value_ms / cls.UNITS_IN_MILLISECONDS[to_unit]


def execute(*args):
    """Execute shell commands."""
    import subprocess
    subprocess.call(args, stdout=subprocess.DEVNULL)


def enumerate_slice(seq, head, tail=None):
    """Generate `index, value` pairs for slice `seq [head:tail]`.

       >>> _show (enumerate_slice (range (7), 0))
       [(0, 0), (1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)]
       >>> _show (enumerate_slice (range (20), 5, 10))
       [(5, 5), (6, 6), (7, 7), (8, 8), (9, 9)]
       >>> _show (enumerate_slice ("abcdefghijklmnopqrstuvwxyz", 20))
       [(20, 'u'), (21, 'v'), (22, 'w'), (23, 'x'), (24, 'y'), (25, 'z')]
    """
    i = head
    for v in seq[head:tail]:
        yield i, v
        i += 1


def delete_traffic_policy(Id=None, Version=None):
    """
    Deletes a traffic policy.
    See also: AWS API Documentation

    :example: response = client.delete_traffic_policy(
        Id='string',
        Version=123
    )

    :type Id: string
    :param Id: [REQUIRED]
            The ID of the traffic policy that you want to delete.

    :type Version: integer
    :param Version: [REQUIRED]
            The version number of the traffic policy that you want to delete.

    :rtype: dict
    :return: {}

    """
    pass


def vertex_color_remove():
    """Remove vertex color layer

    """
    pass


def savefile(filename, body, encoding='windows-1251'):
    """
    Сохранение строки в файл
    """
    with open(filename, encoding=encoding, mode='w') as file:
        file.write(body)


def not_none(value):
    """Sets a None value to "None" string"""
    return 'None' if value is None else str(value)


def get_extension_logger(name, extension):
    """Returns a logger instance suitable for logging
        within extensions.
        """


def write_var(var, out_file):
    """Write variant to output file."""
    var = var._replace(pos=str(var.pos))
    out_file.write('{}\n'.format('\t'.join(var)))


def get_term_record(term):
    """Get a single MeSH term record."""
    return {'term_ui': term.findtext('TermUI'), 'name': term.findtext(
        'String'), **term.attrib}


def bounding_box(bw, bh, w, h):
    """
    Returns a tuple (new_width, new_height) which has the property
    that it fits within box_width and box_height and has (close to)
    the same aspect ratio as the original size
    """
    new_width, new_height = w, h
    if bw and new_width > bw:
        new_width = bw
        new_height = new_width / (float(w) / h)
    if bh and new_height > bh:
        new_height = bh
        new_width = new_height * (float(w) / h)
    return new_width, new_height


@classmethod
def escape_options(cls, options):
    """
        Escapes the items in the *options* list and prepends a '-' if
        necessairy.
        If *options* is None, the empty string will be returned.

        >>> TS3Escape.options_to_str(None)
        ''
        >>> TS3Escape.options_to_str([None, 'permsid', '-virtual'])
        '-permsid -virtual'

        :arg options: A list with the options.
        :type options: None or a list of strings.
        """
    if options is None:
        return str()
    tmp = list()
    for i, e in enumerate(options):
        if e is None:
            continue
        elif not e.startswith('-'):
            e = '-' + e
        tmp.append(e)
    tmp = ' '.join(tmp)
    return tmp


def cyclic_toggle():
    """Toggle cyclic for selected splines

    """
    pass


@staticmethod
def getsizeof(value):
    """Return the size of a cache element's value."""
    return 1


def get_remote_ip(request):
    """Resolves and returns client IP."""
    forwarded = request.META.get('HTTP_X_FORWARDED_FOR')
    ip = request.META.get('REMOTE_ADDR')
    if forwarded is not None:
        ip = forwarded.split(',')[-1].strip()
    return ip


@classmethod
def from_lout(cls, path=None, transform_2d=None, **kwargs):
    """Create a Sensor instance from a ``*.lout`` file"""
    kwargs['transform_2d'] = transform_2d
    locs = []
    names = []
    with open(path) as fileobj:
        fileobj.readline()
        for line in fileobj:
            w, x, y, t, f, name = line.split('\t')
            x = float(x)
            y = float(y)
            locs.append((x, y, 0))
            names.append(name)
    return cls(locs, names, **kwargs)


def type_names(prefix, sizerange):
    """
        Helper for type name generation, like: bytes1 .. bytes32

        Assumes that the size range passed in is valid.
        """
    namelist = []
    for i in sizerange:
        namelist.append(prefix + str(i))
    return tuple(namelist)


def rreplace(s, old, new, occurrence):
    """Convenience function from:
    https://stackoverflow.com/questions/2556108/    rreplace-how-to-replace-the-last-occurrence-of-an-expression-in-a-string
    """
    li = s.rsplit(old, occurrence)
    return new.join(li)


def _queue_iterator(queue):
    """Represents iterator of the given queue.

    Parameters
    ----------
    queue : Queue
        Given queue.

    Yields
    ------
    str
        Current item of queue.

    """
    iterations = queue.qsize()
    for _ in range(iterations):
        var = queue.get()
        yield var
        queue.put(var)


def rx_channel_phase_bias_compensation(rx_channel_compensations, input,
    num_antennas):
    """Compensation of rx channel phase bias.

    Args:
        rx_channel_compensations: rx channel compensation coefficient.
        input: complex number.
        num_antennas: number of symbols.
    """
    azimuth_values = input[:num_antennas]
    rx_channel_compensations_values = rx_channel_compensations[:num_antennas]
    Re = rx_channel_compensations_values * (azimuth_values.imag -
        azimuth_values.real)
    Im = rx_channel_compensations_values * (azimuth_values.imag +
        azimuth_values.real)
    input[:num_antennas] = Re + 1.0j * Im
    return


def vector_is_zero(vector_in, tol=1e-07):
    """ Checks if the input vector is a zero vector.

    :param vector_in: input vector
    :type vector_in: list, tuple
    :param tol: tolerance value
    :type tol: float
    :return: True if the input vector is zero, False otherwise
    :rtype: bool
    """
    if not isinstance(vector_in, (list, tuple)):
        raise TypeError('Input vector must be a list or a tuple')
    res = [(False) for _ in range(len(vector_in))]
    for idx in range(len(vector_in)):
        if abs(vector_in[idx]) < tol:
            res[idx] = True
    return all(res)


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


def is_token_subtype(ttype, other):
    """
    Return True if ``ttype`` is a subtype of ``other``.

    exists for backwards compatibility. use ``ttype in other`` now.
    """
    return ttype in other


@staticmethod
def __get_parent_h2(album_a_tag):
    """Given the soup of an album's <a> tag, get its h2 parent"""
    return album_a_tag.parent.parent


def ver_mlsag_assert(pk, rv, dsRows):
    """
    Initial params verification for ver_mlsag
    :param pk:
    :param rv:
    :param dsRows:
    :return:
    """
    cols = len(pk)
    if cols < 2:
        raise ValueError('Error! What is c if cols = 1!')
    rows = len(pk[0])
    if rows == 0:
        raise ValueError('Empty pk')
    for i in range(cols):
        if len(pk[i]) != rows:
            raise ValueError('pk is not rectangular')
    if len(rv.II) != dsRows:
        raise ValueError('Bad II size')
    if len(rv.ss) != cols:
        raise ValueError('Bad rv.ss size')
    for i in range(cols):
        if len(rv.ss[i]) != rows:
            raise ValueError('rv.ss is not rectangular')
    if dsRows > rows:
        raise ValueError('Bad dsRows value')
    return rows, cols


def _(x):
    """Identity function for string extraction."""
    return x


def isdistinct(seq):
    """ All values in sequence are distinct

    >>> isdistinct([1, 2, 3])
    True
    >>> isdistinct([1, 2, 1])
    False

    >>> isdistinct("Hello")
    False
    >>> isdistinct("World")
    True
    """
    if iter(seq) is seq:
        seen = set()
        seen_add = seen.add
        for item in seq:
            if item in seen:
                return False
            seen_add(item)
        return True
    else:
        return len(seq) == len(set(seq))


def time_in_range(start, end, x):
    """Return true if x is in the range [start, end]"""
    if start <= end:
        return start <= x <= end
    else:
        return start <= x or x <= end


@staticmethod
def endpoint_updated(endpoint, old_properties):
    """
        An end point is updated

        :param endpoint: The updated endpoint
        :param old_properties: Previous properties of the endpoint
        """
    return


def collatz(n):
    """Collatz猜想:也叫3n+1猜想，给一个正整数，如果是偶数，则减半；如果是奇数，则变为它的三倍加一。直到变为一停止"""
    if n > 1 and isinstance(n, int):
        total = 0
        while n != 1:
            if n % 2 == 0:
                n /= 2
            else:
                n = 3 * n + 1
            total += 1
    else:
        raise TypeError('类型错误。必须是大于1的整数')
    return total


def create_cluster_security_group(ClusterSecurityGroupName=None,
    Description=None, Tags=None):
    """
    Creates a new Amazon Redshift security group. You use security groups to control access to non-VPC clusters.
    For information about managing security groups, go to Amazon Redshift Cluster Security Groups in the Amazon Redshift Cluster Management Guide .
    See also: AWS API Documentation

    :example: response = client.create_cluster_security_group(
        ClusterSecurityGroupName='string',
        Description='string',
        Tags=[
            {
                'Key': 'string',
                'Value': 'string'
            },
        ]
    )

    :type ClusterSecurityGroupName: string
    :param ClusterSecurityGroupName: [REQUIRED]
            The name for the security group. Amazon Redshift stores the value as a lowercase string.
            Constraints:
            Must contain no more than 255 alphanumeric characters or hyphens.
            Must not be 'Default'.
            Must be unique for all security groups that are created by your AWS account.
            Example: examplesecuritygroup

    :type Description: string
    :param Description: [REQUIRED]
            A description for the security group.

    :type Tags: list
    :param Tags: A list of tag instances.
            (dict) --A tag consisting of a name/value pair for a resource.
            Key (string) --The key, or name, for the resource tag.
            Value (string) --The value for the resource tag.

    :rtype: dict
    :return: {
        'ClusterSecurityGroup': {
            'ClusterSecurityGroupName': 'string',
            'Description': 'string',
            'EC2SecurityGroups': [
                {
                    'Status': 'string',
                    'EC2SecurityGroupName': 'string',
                    'EC2SecurityGroupOwnerId': 'string',
                    'Tags': [
                        {
                            'Key': 'string',
                            'Value': 'string'
                        },
                    ]
                },
            ],
            'IPRanges': [
                {
                    'Status': 'string',
                    'CIDRIP': 'string',
                    'Tags': [
                        {
                            'Key': 'string',
                            'Value': 'string'
                        },
                    ]
                },
            ],
            'Tags': [
                {
                    'Key': 'string',
                    'Value': 'string'
                },
            ]
        }
    }

    """
    pass


def bC_H_HSO4_HMW84(T, P):
    """c-a: hydrogen bisulfate [HMW84]."""
    b0 = 0.2065
    b1 = 0.5556
    b2 = 0.0
    C0 = 0
    C1 = 0
    alph1 = 2
    alph2 = -9
    omega = -9
    valid = T == 298.15
    return b0, b1, b2, C0, C1, alph1, alph2, omega, valid


def post_init_hook(cr, registry):
    """ Set value for order_sequence on old records """
    cr.execute(
        """
        update purchase_order
        set order_sequence = true
        where state not in ('draft', 'cancel')
        """
        )


def line_search_aggregates(line):
    """get the aggregrates statement eg in `search publications return funders aggregate altmetric_median sort by rcr_avg`
        TODO: return multiple return values not just one
    """
    l = line.split()
    if 'aggregate' in l:
        i = l.index('aggregate')
        if len(l) > i + 2:
            return l[i + 1]
    else:
        return None


def list_tags_for_resource(ResourceType=None, ResourceId=None):
    """
    Returns a list of the tags assigned to the specified resource.
    See also: AWS API Documentation

    :example: response = client.list_tags_for_resource(
        ResourceType='ManagedInstance'|'MaintenanceWindow'|'Parameter',
        ResourceId='string'
    )

    :type ResourceType: string
    :param ResourceType: [REQUIRED]
            Returns a list of tags for a specific resource type.

    :type ResourceId: string
    :param ResourceId: [REQUIRED]
            The resource ID for which you want to see a list of tags.

    :rtype: dict
    :return: {
        'TagList': [
            {
                'Key': 'string',
                'Value': 'string'
            },
        ]
    }

    """
    pass


def decode_response(client_message, to_object=None):
    """ Decode response from client message"""
    parameters = dict(response=None)
    parameters['response'] = client_message.read_int()
    return parameters


def ToSub(x, y):
    """
    A Simple Function to Subtract two numbers.
    """
    return x - y


def predicative(adjective):
    """ Returns the predicative adjective (lowercase): belles => beau.
    """
    w = adjective.lower()
    if w.endswith(('ais', 'ois')):
        return w
    if w.endswith(('és', 'ée', 'ées')):
        return w.rstrip('es')
    if w.endswith(('que', 'ques')):
        return w.rstrip('s')
    if w.endswith(('nts', 'nte', 'ntes')):
        return w.rstrip('es')
    if w.endswith('eaux'):
        return w.rstrip('x')
    if w.endswith(('aux', 'ale', 'ales')):
        return w.rstrip('uxles') + 'l'
    if w.endswith(('rteuse', 'rteuses', 'ailleuse')):
        return w.rstrip('es') + 'r'
    if w.endswith(('euse', 'euses')):
        return w.rstrip('es') + 'x'
    if w.endswith(('els', 'elle', 'elles')):
        return w.rstrip('les') + 'el'
    if w.endswith(('ifs', 'ive', 'ives')):
        return w.rstrip('es')[:-2] + 'if'
    if w.endswith(('is', 'ie', 'ies')):
        return w.rstrip('es')
    if w.endswith(('enne', 'ennes')):
        return w.rstrip('nes') + 'en'
    if w.endswith(('onne', 'onnes')):
        return w.rstrip('nes') + 'n'
    if w.endswith(('igne', 'ignes', 'ingue', 'ingues')):
        return w.rstrip('s')
    if w.endswith(('ène', 'ènes')):
        return w.rstrip('s')
    if w.endswith(('ns', 'ne', 'nes')):
        return w.rstrip('es')
    if w.endswith(('ite', 'ites')):
        return w.rstrip('es')
    if w.endswith(('is', 'ise', 'ises')):
        return w.rstrip('es') + 's'
    if w.endswith(('rice', 'rices')):
        return w.rstrip('rices') + 'eur'
    if w.endswith(('iers', 'ière', 'ières')):
        return w.rstrip('es')[:-3] + 'ier'
    if w.endswith(('ette', 'ettes')):
        return w.rstrip('tes') + 'et'
    if w.endswith(('rds', 'rde', 'rdes')):
        return w.rstrip('es')
    if w.endswith(('nds', 'nde', 'ndes')):
        return w.rstrip('es')
    if w.endswith(('us', 'ue', 'ues')):
        return w.rstrip('es')
    return w.rstrip('s')


def diff_jaccard(str1, str2):
    """
    Calculates the Jaccard similarity between two strings.

    :param str1: First string.
    :param str2: Second string.
    :return: float in the [0, 1] interval
    """
    assert type(str1) == list and type(str2) == list
    assert type(str1[0]) == str and type(str2[0]) == str
    a = set(str1)
    b = set(str2)
    c = a.intersection(b)
    return float(len(c)) / (len(a) + len(b) - len(c))


def get_np(osi):
    """Get total number of processors."""
    return osi.to_process('getNP', [])


def is_list_like(value):
    """Whether value is tuple or list"""
    return isinstance(value, (tuple, list))


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


@classmethod
def load(cls, load_path, env=None, custom_objects=None, **kwargs):
    """
        Load the model from file

        :param load_path: (str or file-like) the saved parameter location
        :param env: (Gym Environment) the new environment to run the loaded model on
            (can be None if you only need prediction from a trained model)
        :param custom_objects: (dict) Dictionary of objects to replace
            upon loading. If a variable is present in this dictionary as a
            key, it will not be deserialized and the corresponding item
            will be used instead. Similar to custom_objects in
            `keras.models.load_model`. Useful when you have an object in
            file that can not be deserialized.
        :param kwargs: extra arguments to change the model when loading
        """
    data, params = cls._load_from_file(load_path, custom_objects=custom_objects
        )
    if 'policy_kwargs' in kwargs and kwargs['policy_kwargs'] != data[
        'policy_kwargs']:
        raise ValueError(
            'The specified policy kwargs do not equal the stored policy kwargs. Stored kwargs: {}, specified kwargs: {}'
            .format(data['policy_kwargs'], kwargs['policy_kwargs']))
    model = cls(policy=data['policy'], env=None, _init_setup_model=False)
    model.__dict__.update(data)
    model.__dict__.update(kwargs)
    model.set_env(env)
    model.setup_model()
    model.load_parameters(params)
    return model


@classmethod
def load_pkcs1(cls, keyfile, format='PEM'):
    """Loads a key in PKCS#1 DER or PEM format.

        :param keyfile: contents of a DER- or PEM-encoded file that contains
            the key.
        :type keyfile: bytes
        :param format: the format of the file to load; 'PEM' or 'DER'
        :type format: str

        :return: the loaded key
        :rtype: AbstractKey
        """
    methods = {'PEM': cls._load_pkcs1_pem, 'DER': cls._load_pkcs1_der}
    method = cls._assert_format_exists(format, methods)
    return method(keyfile)


@staticmethod
def __parse_options_dict(options_str):
    """Convert the options string into a dict.

        Keyword Args:
            options_str (str): The options string that will
                be seperated into a dictionary based on the
                `&` separator
        """
    opts = options_str.split('&')
    res = {}
    for opt in opts:
        key, value = opt.split('=')
        res[key] = value
    return res


def _siftdown_max(heap, startpos, pos):
    """Maxheap variant of _siftdown"""
    newitem = heap[pos]
    while pos > startpos:
        parentpos = pos - 1 >> 1
        parent = heap[parentpos]
        if parent < newitem:
            heap[pos] = parent
            pos = parentpos
            continue
        break
    heap[pos] = newitem


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

        :param TeamFolderPermanentlyDeleteType val:
        :rtype: EventType
        """
    return cls('team_folder_permanently_delete', val)


def lower(f, c, o=1):
    """Determine whether or not a series value is lower than
    the value ``o`` periods back.

    Parameters
    ----------
    f : pandas.DataFrame
        Dataframe containing the column ``c``.
    c : str
        Name of the column in the dataframe ``f``.
    o : int, optional
        Offset value for shifting the series.

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

    """
    new_column = f[c] < f[c].shift(o)
    return new_column


@classmethod
def unregister(cls):
    """Removes all plugin meta information and makes it undiscoverable."""
    cls._meta_clear()


@staticmethod
def item_in(items):
    """
        Single item is in item sets.

        Example::

            {"item_type": "Fruit"}, "Fruit" in ["Fruit", "Meat"]
        """
    return {'$in': items}


def render_pep440_pre(pieces):
    """TAG[.post.devDISTANCE] -- No -dirty.

    Exceptions:
    1: no tags. 0.post.devDISTANCE
    """
    if pieces['closest-tag']:
        rendered = pieces['closest-tag']
        if pieces['distance']:
            rendered += '.post.dev%d' % pieces['distance']
    else:
        rendered = '0.post.dev%d' % pieces['distance']
    return rendered


def lambd_NH3_F_CB89(T, P):
    """n-a: ammonia fluoride [CB89]."""
    lambd = 0.091
    valid = T == 298.15
    return lambd, valid


def ZopeFindAndApply(obj, obj_ids=None, obj_metatypes=None, obj_searchterm=
    None, obj_expr=None, obj_mtime=None, obj_mspec=None, obj_permission=
    None, obj_roles=None, search_sub=0, REQUEST=None, result=None, pre='',
    apply_func=None, apply_path=''):
    """Zope Find interface and apply"""


@classmethod
def constraints(cls):
    """
        Get all constraints enforced by class.
        A constraint is used when the middleware is instantiated with a child
        middleware (``protocol1+protocol2://``). The child middleware must be
        a subclass of each class specified by the constraint.

        :returns: list of constraints
        :rtype: list
        """
    bases = cls.mro()
    result = []
    for base in reversed(bases):
        if hasattr(base, '__constraints__'):
            for constraint in base.__constraints__:
                if constraint not in result:
                    result.append(constraint)
    return result


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


@classmethod
def _deriveLogin(cls, email, firstName, lastName, userName=None):
    """
        Attempt to automatically create a login name from existing user
        information from OAuth2 providers. Attempts to generate it from the
        username on the provider, the email address, or first and last name. If
        not possible, returns None and it is left to the caller to generate
        their own login for the user or choose to fail.

        :param email: The email address.
        :type email: str
        """
    for login in cls._generateLogins(email, firstName, lastName, userName):
        login = login.lower()
        if cls._testLogin(login):
            return login
    raise Exception('Could not generate a unique login name for %s (%s %s)' %
        (email, firstName, lastName))


@classmethod
def from_image(klass, img):
    """ Class method to create new instance of own class from `img`

        Parameters
        ----------
        img : ``spatialimage`` instance
           In fact, an object with the API of ``FileBasedImage``.

        Returns
        -------
        cimg : ``spatialimage`` instance
           Image, of our own class
        """
    raise NotImplementedError()


def properties_add(data_path: str=''):
    """Undocumented contribute <https://developer.blender.org/T51061>

    :param data_path: Property Edit, Property data_path edit
    :type data_path: str
    """
    pass


def response_content_is_login_page(response_content):
    """Returns True if the provided response_content seems to be from the Vilfo login page."""
    detectors = ['<title>Login | Vilfo</title>', '<Login-Form']
    detected_count = 0
    for detector in detectors:
        if detector in str(response_content):
            detected_count += 1
    return detected_count >= len(detectors) / 2


@staticmethod
def return_integer(obj):
    """Convert obj into an integer

        Parameters
        ----------
        obj: str, float, int
            object you wish to convert to an integer
        """
    return int(obj)


def decrypt(data):
    """Returns the decrypted data"""


def pairs(csv, keys, skip=0):
    """Create a pairs plot for keys in the given dataset.
    """
    import pylab as pl
    n = len(keys)
    if isinstance(csv, dict):
        csv = [csv]
    for i, key_i in enumerate(keys):
        for j, key_j in enumerate(keys):
            pl.subplot(n, n, i * n + j + 1)
            for csvi in csv:
                if i == j:
                    pl.hist(csvi[key_i][skip:], 20, log=True)
                else:
                    pl.plot(csvi[key_j][skip:], csvi[key_i][skip:], '.')
            if i == 0:
                pl.title(key_j)
            if j == 0:
                pl.ylabel(key_i)


@staticmethod
def serialize(store):
    """Serialize given Translate Toolkit store."""
    return bytes(store)


def combine(text, starts, append):
    """Combine intermediate tweet representation to one str"""
    strlist = []
    i = 0
    while True:
        oldi = i
        while i not in starts and i < len(text):
            i += 1
        strlist.append(text[oldi:i])
        if not i < len(text):
            break
        strlist.append(starts[i]['html'])
        i = starts[i]['indices'][1]
    strlist.append(append)
    return ''.join(strlist)


def getInt(c):
    """
    get the integer value of byte.

    :param c: char/byte

    Returns the integer from the byte
    """
    if type(c) == int:
        return c
    elif type(c) == str and len(c) == 1:
        return int(ord(c))
    else:
        return None


def ansi_highlight_code(python_code, ansi_colors):
    """Adds ANSI color code to make python_code pretty.

    Args:
      python_code (str): Python 3 code to prettify.
      ansi_colors (int): Number of colors to use, as returned by
          count_ansi_colors().

    Returns:
      str: The prettified Python code.
    """
    import pygments
    import pygments.lexers
    import pygments.formatters
    if ansi_colors >= 256:
        formatter = pygments.formatters.Terminal256Formatter(bg='dark')
    elif ansi_colors >= 8:
        formatter = pygments.formatters.TerminalFormatter(bg='dark')
    else:
        return python_code
    lexer = pygments.lexers.get_lexer_by_name('python3')
    return pygments.highlight(python_code, lexer, formatter)


def log(data):
    """Handle logging or printing in one place."""
    print(data)


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


def view_zoom_ratio(ratio: float=1.0):
    """Change zoom ratio of sequencer preview

    :param ratio: Ratio, Zoom ratio, 1.0 is 1:1, higher is zoomed in, lower is zoomed out
    :type ratio: float
    """
    pass


@staticmethod
def get_preset_dictionary(root, rule_id):
    """Get the presets from a rule based on rule ID and returns a dictionary with all the key-value pairs."""
    preset_dictionary = {}
    directives = root.find("rule[@id='" + rule_id + "']/directives")
    for directive in directives:
        preset_dictionary[directive.attrib['preset']] = float(directive.
            find('then').attrib['setpoint'])
    return preset_dictionary


def forget(environ, identity):
    """ On egress (challenge required):

        args -> [ (header-name, header-value), ...] | None

        Return a list of headers suitable for allowing the requesting
        system to forget the identification information (e.g. a
        Set-Cookie header with an expires date in the past).  Return
        None if no headers need to be set.  These headers will be
        included in the response provided by the challenge app.
        """


def expected_parameters_from_cli(opts):
    """Parses the --expected-parameters arguments from the `plot_posterior`
    option group.

    Parameters
    ----------
    opts : ArgumentParser
        The parsed arguments from the command line.

    Returns
    -------
    dict
        Dictionary of parameter name -> expected value. Only parameters that
        were specified in the --expected-parameters option will be included; if
        no parameters were provided, will return an empty dictionary.
    """
    expected = {}
    for x in opts.expected_parameters:
        x = x.split(':')
        if len(x) != 2:
            raise ValueError(
                'option --expected-paramters not specified correctly; see help'
                )
        expected[x[0]] = float(x[1])
    return expected


def _concat_tuples(tagging):
    """
  param: tuples of [(word, tag), ...]
  return: string, 'w1/t1 w2/t2 ...'
  """
    TOKEN_BLANK = ' '
    wl = []
    for x, y in tagging:
        wl.append(x + '/' + y)
    concat_str = TOKEN_BLANK.join(wl)
    return concat_str


@staticmethod
def default_inherit(parent=None):
    """
        Default inherited function.

        :param parent: the parent structure
        :return: None
        """
    return None


def are_near(d1, d2, ppmtol):
    """Predicate: flags if two entries should belong to the same compound"""
    reltol = ppmtol * 1e-06
    if d1['_sample'] == d2['_sample']:
        return False
    m1, m2 = d1['m/z'], d2['m/z']
    if (m2 - m1) / m2 <= reltol:
        return True
    return False


@classmethod
def for_testnet(cls):
    """ Creates a ``Client`` instance for use with the NEO Test Net. """
    return cls(host='test1.cityofzion.io', port=8880)


@classmethod
def create_read(cls, value):
    """ Create a new read capacity from a response """
    return cls(value['CapacityUnits'], 0)


def add_gc_creds(parser):
    """Adds GC cred arguemnts"""
    parser.add_argument('--gs-json-key-file', required=False, help=
        'location of the Google Cloud key.json file')


def clearbackup(tr, backupname):
    """Clear backup file"""


def one_cross_entropy_ic(y, preds):
    """
    Compute the IC for one cross-entropy

    @param y: the outcome
    @param preds: the predictions based on a given subset of features

    @return the IC for cross-entropy
    """
    import sklearn.metrics as skm
    import numpy as np
    cross_entropy = -2 * skm.log_loss(y_true=y, y_pred=preds, normalize=True)
    p = np.mean(y, axis=0)
    ic_cross_entropy = -2 * np.sum(y * np.log(preds), axis=1) - cross_entropy
    return ic_cross_entropy


def to_option(value):
    """
    Normalizes an option for outputting to a config file.
    """
    if value is None:
        return value
    return str(value)


def login(request):
    """Login view for GET requests."""
    logged_in = request.authenticated_userid is not None
    if logged_in:
        return {'logged_in': True, 'form_enabled': False, 'status':
            u'Already logged in', 'status_type': u'info'}
    status = u''
    status_type = u''
    return {'form_enabled': True, 'status_type': status_type, 'status':
        status, 'logged_in': False, 'username': request.params.get(
        'username', u'')}


def split_words(s):
    """Разделяет текст на слова по-умному для подсчёта различий."""
    ALPHA = 1
    SPACE = 2
    OTHER = 0
    result = []
    last = OTHER
    tag = False
    for char in s:
        current = OTHER
        if char.isspace():
            current = SPACE
        elif char.isalpha() or char.isdigit():
            current = ALPHA
        if char == '\n':
            result.append(char)
            tag = False
        elif current == SPACE:
            if tag or not result or last == SPACE or last == OTHER:
                result.append(char)
                tag = False
            else:
                result[-1] += char
        elif char == '<':
            result.append(char)
            tag = True
        elif tag and (current == ALPHA or char == '=' or char == '/' or
            char == '>'):
            result[-1] += char
            if char == '>':
                tag = False
        elif current != OTHER and current == last:
            result[-1] += char
        elif current == OTHER and last == ALPHA and char in '.,?!:;':
            result[-1] += char
        else:
            result.append(char)
            tag = False
        last = current
    return result


def properties():
    """Toggle the properties region visibility

    """
    pass


def save(addr, data, **kward):
    """dp.save('file.xlsx', [1,2,3,4]) -> save dataset into file
        more info on help(dp.DataSet.save)
    """
    from .core import DataSet
    if not isinstance(data, DataSet):
        data = DataSet(data, sheet=kward.get('sheet', 'sheet0'))
    data.save(addr, **kward)


def connect_individuals(pop):
    """
    Makes the connections in the genealogy from parents to children
    and vice versa.

    :param population: Set of individuals to connect
    :type population: IndividualContainer

    :rtype void:
    """
    for ind in pop.individuals:
        fam, _ = ind.label
        ind.father = pop[fam, ind.father] if ind.father != '0' else None
        ind.mother = pop[fam, ind.mother] if ind.mother != '0' else None
        ind.register_with_parents()


def fetch_deletion(chrom, st, cigar):
    """ fetch deletion regions defined by cigar. st must be zero based
	return list of tuple of (chrom,st, end)
	"""
    chrom_st = st
    del_bound = []
    for c, s in cigar:
        if c == 0:
            chrom_st += s
        elif c == 1:
            continue
        elif c == 2:
            del_bound.append((chrom, chrom_st, chrom_st + s))
            chrom_st += s
        elif c == 3:
            chrom_st += s
        elif c == 4:
            chrom_st += s
        else:
            continue
    return del_bound


def register_patch_baseline_for_patch_group(BaselineId=None, PatchGroup=None):
    """
    Registers a patch baseline for a patch group.
    See also: AWS API Documentation

    :example: response = client.register_patch_baseline_for_patch_group(
        BaselineId='string',
        PatchGroup='string'
    )

    :type BaselineId: string
    :param BaselineId: [REQUIRED]
            The ID of the patch baseline to register the patch group with.

    :type PatchGroup: string
    :param PatchGroup: [REQUIRED]
            The name of the patch group that should be registered with the patch baseline.

    :rtype: dict
    :return: {
        'BaselineId': 'string',
        'PatchGroup': 'string'
    }

    """
    pass


def consolidateBy(requestContext, seriesList, consolidationFunc):
    """
    Takes one metric or a wildcard seriesList and a consolidation function
    name.

    Valid function names are 'sum', 'average', 'min', and 'max'

    When a graph is drawn where width of the graph size in pixels is smaller
    than the number of datapoints to be graphed, Graphite consolidates the
    values to to prevent line overlap. The consolidateBy() function changes
    the consolidation function from the default of 'average' to one of 'sum',
    'max', or 'min'. This is especially useful in sales graphs, where
    fractional values make no sense and a 'sum' of consolidated values is
    appropriate.

    Example::

        &target=consolidateBy(Sales.widgets.largeBlue, 'sum')
        &target=consolidateBy(Servers.web01.sda1.free_space, 'max')

    """
    for series in seriesList:
        series.consolidationFunc = consolidationFunc
        series.name = 'consolidateBy(%s,"%s")' % (series.name, series.
            consolidationFunc)
        series.pathExpression = series.name
    return seriesList


def save_parameters(params, filepath, fileformat='h5'):
    """Save all layer parameters to an HDF5 file."""
    if fileformat == 'pkl':
        import pickle
        pickle.dump(params, open(filepath + '.pkl', str('wb')))
    else:
        import h5py
        with h5py.File(filepath, mode='w') as f:
            for i, p in enumerate(params):
                if i < 10:
                    j = '00' + str(i)
                elif i < 100:
                    j = '0' + str(i)
                else:
                    j = str(i)
                f.create_dataset('param_' + j, data=p)


def psi_Na_AsO4_Cl_M83(T, P):
    """c-a-a': sodium arsenate chloride [M83]."""
    psi = 0
    valid = T == 298.15
    return psi, valid


def just_sid(sid, pos):
    """Use just the sid (ignoring the chromosome, genetic distance, and basepair distance) in the file.
    """
    return sid


def exec_compat(expression, globals, locals=None):
    """
    Compatibility exec function for python2 and python3.

    The python2 exec() statement is bound to the following restriction:

        If exec is used in a function and the function contains a nested
        block with free variables, the compiler will raise a SyntaxError
        unless the exec explicitly specifies the local namespace for the
        exec. (In  other words, "exec  obj" would be illegal,  but "exec
        obj in ns" would be legal.)

        http://www.python.org/dev/peps/pep-0227/

    It seems the 3-tuple form of the exec-statement is not recognized as
    explicitly  specifying the  local namespace  therefore creating  the
    need to call it from an intermediate function without nested scope.

    The  3-tuple   form  of   the  exec   statement  is   mandatory  for
    compatibility between python2 and python3.

    http://docs.python.org/2/reference/simple_stmts.html#the-exec-statement
    http://docs.python.org/3.3/library/functions.html?highlight=exec#exec
    """
    exec(expression, globals, locals)


def ex2err(ex):
    """Convert a Cinder Exception to a Nexenta Error."""
    return ex.msg


@classmethod
def get_type_of_payers_for_redelivery(cls):
    """
        Method for fetching info about types of payers for redelivery.

        :example:
            ``Common.get_type_of_payers_for_redelivery()``
        :return:
            dictionary with info about types of payers for redelivery
        :rtype:
            dict
        """
    req = cls.send(method='getTypesOfPayersForRedelivery')
    return req


def determine_when_discovered_sne_disappear(log, redshiftArray,
    limitingMags, observedFrameLightCurveInfo, ripeDayList, plot=True):
    """
    *Given the observed frame lightcurve, determine when the discovered SNe become too faint to be detected.*

    **Key Arguments:**
        - ``log`` -- logger
        - ``redshiftArray`` -- the array of random redshifts
        - ``observedFrameLightCurveInfo`` -- the observed franme lightcurve info (dictionary)
        - ``ripeDayList`` -- a list of dictionaries describing if the object is discoverable in each filter and finally if it is discoverable in any filter.
        - ``plot`` -- generate plots?

    **Return:**
        - ``disappearDayList`` -- a list of dictionaries describing the time relative to peak that the SN reaches the limiting mag of the survey
    """
    import math
    filters = ['g', 'r', 'i', 'z']
    models = ['he80', 'he100', 'he130']
    disappearDayList = []
    for item in range(len(redshiftArray)):
        disappearDayDict = {}
        if not ripeDayList[item]['any']:
            disappearDayDict['any'] = False
            for ffilter in filters:
                disappearDayDict[ffilter] = False
        else:
            for ffilter in filters:
                if not ripeDayList[item][ffilter]:
                    disappearDayDict[ffilter] = False
                else:
                    lightCurveEndDay = observedFrameLightCurveInfo[item][
                        'endOfLightcurveDay']
                    lowerLimit = 0.0
                    upperLimit = lightCurveEndDay
                    disappearDay = upperLimit
                    magGuess = observedFrameLightCurveInfo[item]['lightCurves'
                        ][ffilter](disappearDay)
                    magDiff = limitingMags[ffilter] - magGuess
                    log.info(
                        'item %s disappearDay %s magGuess %s - going higher' %
                        (item, disappearDay, magGuess))
                    if magGuess > limitingMags[ffilter]:
                        while math.fabs(magDiff) > 0.01:
                            if magGuess > limitingMags[ffilter]:
                                log.info(
                                    'item %s disappearDay %s magGuess %s - going higher'
                                     % (item, disappearDay, magGuess))
                                upperLimit = disappearDay
                                disappearDay = lowerLimit + (upperLimit -
                                    lowerLimit) / 2.0
                                magGuess = observedFrameLightCurveInfo[item][
                                    'lightCurves'][ffilter](disappearDay)
                            elif magGuess < limitingMags[ffilter]:
                                log.info('item %s disappearDay %s' % (item,
                                    disappearDay))
                                lowerLimit = disappearDay
                                disappearDay = lowerLimit + (upperLimit -
                                    lowerLimit) / 2.0
                                magGuess = observedFrameLightCurveInfo[item][
                                    'lightCurves'][ffilter](disappearDay)
                            magDiff = limitingMags[ffilter] - magGuess
                    else:
                        disappearDay = 'N.E.D.'
                        log.warning(
                            "not enough data to determine when the SN disappears fainter than the survey's limiting mag"
                            )
                    if type(disappearDay) != str:
                        disappearDay = float('%5.3f' % (disappearDay,))
                    disappearDayDict[ffilter] = disappearDay
            disappearDayDict['any'] = False
            for ffilter in filters:
                if disappearDayDict[ffilter] and disappearDayDict[ffilter
                    ] != 'N.E.D.':
                    disappearDayDict['any'] = True
        disappearDayList.append(disappearDayDict)
    log.info('disappearDayList %s' % (disappearDayList,))
    return disappearDayList


def send(message, type=u'message'):
    """Send a message to this source.

        Message can either be a unicode string or an IMessage object.

        """


def _print_progress(message):
    """Progress reporting function for long-running operations"""
    print(message)


def has_header(path, encoding='utf-8'):
    """
    Auto-detect if csv file has header.
    """
    from pandas import read_csv
    df0 = read_csv(path, header=None, nrows=10, skipinitialspace=True,
        encoding=encoding)
    df1 = read_csv(path, nrows=10, skipinitialspace=True, encoding=encoding)
    return tuple(df0.dtypes) != tuple(df1.dtypes)


@classmethod
def _connexion_to_framework_response(cls, response, mimetype, extra_context
    =None):
    """ Cast ConnexionResponse to framework response class """
    flask_response = cls._build_response(mimetype=response.mimetype or
        mimetype, content_type=response.content_type, headers=response.
        headers, status_code=response.status_code, data=response.body,
        extra_context=extra_context)
    return flask_response


def Shell(device, *command):
    """Runs a command on the device and prints the stdout.

    Args:
      command: Command to run on the target.
    """
    if command:
        return device.StreamingShell(' '.join(command))
    else:
        terminal_prompt = device.InteractiveShell()
        print(terminal_prompt.decode('utf-8'))
        while True:
            cmd = input('> ')
            if not cmd:
                continue
            elif cmd == 'exit':
                break
            else:
                stdout = device.InteractiveShell(cmd, strip_cmd=True, delim
                    =terminal_prompt, strip_delim=True)
                if stdout:
                    if isinstance(stdout, bytes):
                        stdout = stdout.decode('utf-8')
                        print(stdout)
        device.Close()


def validate_keys(name, d, keys):
    """
    Assert that all keys exist in d, and that they are non-empty strings.
    If any invalid keys found, raise TypeError.
    """
    try:
        for key in keys:
            assert isinstance(d[key], str)
            assert len(d[key]) > 0
    except TypeError:
        raise TypeError(f'{name} is not a dict')
    except KeyError:
        raise TypeError(
            f"Missing dict keys for {name}. Expecting: {', '.join(keys)}")
    except AssertionError:
        raise TypeError(
            f'Invalid key values for {name}. Keys must be non-empty strings.')
    return True


@staticmethod
def _get_parts(data):
    """
            split data using | separator and remove first item
            (because the first item is empty)
        """
    parts = data.split('|')[1:]
    return parts


def _check_type(datatype, **kwargs):
    """
    checks is datatype is either "CSPEC" or "CTIME".
    """
    if not isinstance(datatype, str):
        raise ValueError(f'{datatype} is not str - either cspec or ctime')
    if datatype.lower() != 'cspec' and datatype.lower() != 'ctime':
        raise ValueError(
            f'{datatype} not value datatype - either cspec or ctime')
    else:
        return datatype.lower()


def compare(a, b):
    """Python3 replacement for Python 2.x cmp(), see
    https://docs.python.org/3.0/whatsnew/3.0.html#ordering-comparisons
    """
    return (a > b) - (a < b)


def ft_seq(data):
    """performs the fourier transform of a data-set acquired on a Bruker in simultaneous mode
    Processing is performed only along the F2 (F3) axis if in 2D (3D)

    (Bruker QSIM mode)"""
    todo = data.dim
    data.revf().rfft(axis=todo)
    return data


@staticmethod
def _d2s(kvp):
    """Parse dictionary to list of colon-separated address and port.

        :param kvp: dictionary
        :returns: list of colon-separated address and port
        """
    result = []
    for key_val in kvp:
        result.append('%s:%s' % (key_val['address'], key_val['port']))
    return result


def can_paginate(operation_name=None):
    """
    Check if an operation can be paginated.

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

    """
    pass


def plot_all_components(components_img, **kwargs):
    """ Plot the components IC spatial maps in only one brain. """
    from nilearn.plotting import plot_prob_atlas
    from matplotlib import pyplot as plt
    fig = plt.figure(facecolor='white')
    p = plot_prob_atlas(components_img, figure=fig, draw_cross=False, **kwargs)
    p.close()
    return fig


@classmethod
def _from_version_string(cls, s):
    """
        Parse *s* and return a _VersionInfo.
        """
    v = s.split('.')
    if len(v) == 3:
        v.append('final')
    return cls(year=int(v[0]), minor=int(v[1]), micro=int(v[2]),
        releaselevel=v[3])


def add_variational_representations(variational_representation_1,
    variational_representation_2, radices):
    """
    Add two decompositions (by variations) as multiradix numbers.

    :param variational_representation_1: first decomposition
    :param variational_representation_2: second decomposition
    :param radices: radices of decomposition
    :return: summation result (decomposition)
    """
    overflow = 0
    result = []
    for digit_1, digit_2, radix in zip(variational_representation_1,
        variational_representation_2, radices):
        result_digit = digit_1 + digit_2 + overflow
        if result_digit < radix:
            overflow = 0
        else:
            result_digit %= radix
            overflow = 1
        result.append(result_digit)
    return result


def _is_intermediate_subcommand(args):
    """
    Some commands have nested subcommands. These intermediate commands are not executable and don't have a 'func'
    property.
    For example:
    > mcmd add user
    Here, 'add' is the intermediate command.
    """
    return not hasattr(args, 'func')


def count(qry=None):
    """Count items matching query conditions

        Provides a quick way to count items without fetching them from
        database.
        """


def parse_map_file(path):
    """Parse a postfix map file and return values."""
    content = {}
    with open(path) as fp:
        for line in fp:
            if not line or line.startswith('#'):
                continue
            name, value = line.split('=', 1)
            content[name.strip()] = value.strip()
    return content


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

        :param PaperDocDeletedDetails val:
        :rtype: EventDetails
        """
    return cls('paper_doc_deleted_details', val)


def close_window():
    """Closes the pythonGraph window.

    An error is raised if the graphics window is not open.

    .. code-block:: python

        pythonGraph.close_window()

    """
    quit()


def read_magic(fobj):
    """Read magic bytes.

    Parameters
    ----------
    fobj : file-like object
        The file to read from.

    Returns
    -------
    bytes
        magic byte sequence read

    """
    return fobj.read(4)


@classmethod
def get_testing_options(cls):
    """Get testing options for the filter class.

        Returns:
            list: Mutiple dictionaries of keywords and messages that will
                pass/fail for those keywords.

        """
    return [{'pass': [1, 0]}]


def theta_Ca_K_PK74(T, P):
    """c-c': calcium potassium [PK74]."""
    theta = -0.04
    valid = T == 298.15
    return theta, valid


def _get_id(df, player_col, year_col):
    """Aggregate player column and year column."""
    return df[player_col] + '___' + df[year_col].astype(str)


def _single_event_per_dump(events, greedy):
    """Ensure that each dump is associated with a single sensor event.

    This generates a sequence of cleaned-up sensor events (represented by
    indices into the original `events` sequence), which ensures that each dump
    is associated with a single event. When there are multiple events inside
    a dump, pick the final one. In addition, some sensor values designated as
    "greedy" will override non-greedy ones and grab a dump even if it is not
    the final value. In this scenario, move the final (non-greedy) event to the
    next dump by modifying its dump index in the `events` parameter. The
    generator returns up to *N* events but not the special terminal event.

    Parameters
    ----------
    events : mutable sequence of non-negative ints, length *N* + 1
        Monotonic sequence of dump indices associated with each sensor event.
        The last event is one past the last dump (i.e. the total number of
        dumps). Be aware that this parameter is mutated by the function.
    greedy : sequence of bool, length *N*
        Flags indicating whether the sensor value at a given event is "greedy"

    Yields
    ------
    event_index : non-negative int
        Index into `events` sequence of the next cleaned up event (does not
        yield the one-past-last-dump terminal event)

    """
    previous_winning_event = 0
    previous_dump = 0
    for current_event, current_dump in enumerate(events):
        if current_dump > previous_dump:
            assert current_event >= 1, 'First sensor event not at dump 0'
            event_at_dump_start = current_event - 1
            if not greedy[previous_winning_event]:
                previous_winning_event = event_at_dump_start
            winning_dump = events[previous_winning_event]
            if previous_dump <= winning_dump < current_dump:
                yield previous_winning_event
            if event_at_dump_start != previous_winning_event:
                events[event_at_dump_start] += 1
                if current_dump > events[event_at_dump_start]:
                    yield event_at_dump_start
                previous_winning_event = event_at_dump_start
            previous_dump = current_dump
        if current_event < len(greedy) and greedy[current_event]:
            previous_winning_event = current_event


def __enamldef_newobj__(cls, *args):
    """ An enamldef pickler function.

    This function is not part of the public Enaml api.

    """
    instance = cls.__new__(cls, *args)
    cls.__node__(instance)
    return instance


def get_by_path(obj, path):
    """
    Iteratively get on obj for each key in path.

    :param (list|dict) obj: The top-level object.
    :param (tuple[str]|tuple[int]) path: Keys to access parts of obj.

    :return: (*)

    Example:

        >>> figure = {'data': [{'x': [5]}]}
        >>> path = ('data', 0, 'x')
        >>> get_by_path(figure, path)
        [5]
    """
    for key in path:
        obj = obj[key]
    return obj


def get_unix_tput_terminal_size():
    """
    Get the terminal size of a UNIX terminal using the tput UNIX command.
    Ref: http://stackoverflow.com/questions/263890/how-do-i-find-the-width-height-of-a-terminal-window
    """
    import subprocess
    try:
        proc = subprocess.Popen(['tput', 'cols'], stdin=subprocess.PIPE,
            stdout=subprocess.PIPE)
        output = proc.communicate(input=None)
        cols = int(output[0])
        proc = subprocess.Popen(['tput', 'lines'], stdin=subprocess.PIPE,
            stdout=subprocess.PIPE)
        output = proc.communicate(input=None)
        rows = int(output[0])
        return cols, rows
    except (IOError, OSError):
        return None


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

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

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


def conditional_str(prefix, obj, suffix):
    """
    Return a concatenation of prefix, object and suffix.

    Returns empty string if obj is not "truthy" (i.e., not None or empty
    container)
    """
    return ' '.join([prefix, str(obj), suffix]) if obj is not None and len(obj
        ) > 0 else ''


@classmethod
def geom_col_name(cls):
    """
        Return the name of the metadata column used to store the feature
        geometry column.
        """
    return 'f_geometry_column'


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

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

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


def relative_script(lines):
    """Return a script that'll work in a relocatable environment."""
    activate = (
        "import os; activate_this=os.path.join(os.path.dirname(os.path.realpath(__file__)), 'activate_this.py'); exec(compile(open(activate_this).read(), activate_this, 'exec'), dict(__file__=activate_this)); del os, activate_this"
        )
    activate_at = None
    for idx, line in reversed(list(enumerate(lines))):
        if line.split()[:3] == ['from', '__future__', 'import']:
            activate_at = idx + 1
            break
    if activate_at is None:
        activate_at = 1
    return lines[:activate_at] + ['', activate, ''] + lines[activate_at:]


def GetNeighbors(ID, model=None, neighbors=None, mag_range=None, cdpp_range
    =None, aperture_name=None, cadence='lc', **kwargs):
    """
  Return `neighbors` random bright stars on the same module as `EPIC`.

  :param int ID: The target ID number
  :param str model: The :py:obj:`everest` model name. Only used when imposing CDPP bounds. Default :py:obj:`None`
  :param int neighbors: Number of neighbors to return. Default None
  :param str aperture_name: The name of the aperture to use. Select `custom` to call          :py:func:`GetCustomAperture`. Default :py:obj:`None`
  :param str cadence: The light curve cadence. Default `lc`
  :param tuple mag_range: (`low`, `high`) values for the Kepler magnitude. Default :py:obj:`None`
  :param tuple cdpp_range: (`low`, `high`) values for the de-trended CDPP. Default :py:obj:`None`

  """
    raise NotImplementedError('This mission is not yet supported.')


@classmethod
def from_str(cls, value):
    """Convert string to enum element.

        :param str value:
            String with value to convert.
        :returns:
            Enum class object.
        :raises:
            NotImplementedError
        """
    int_value = int(value)
    for item in cls:
        if item.value == int_value:
            return item
    raise NotImplementedError("'{}' is no element of '{}'".format(value,
        cls.__name__))


@classmethod
def help(cls):
    """prints named colors"""
    print('for named colors use :')
    for c in sorted(list(cls.colors.items())):
        print('{:10} {}'.format(*c))


def mesh_add_vertex_to_face_edge(mesh, key, fkey, v):
    """Add an existing vertex of the mesh to an existing face.

    Parameters
    ----------
    mesh : compas.datastructures.Mesh
        The mesh data structure.
    key : hashable
        The identifier of the vertex.
    fkey : hashable
        The identifier of the face.
    v : hashable
        The identifier of the vertex before which the new vertex should be added.

    Notes
    -----
    The algorithm is merely there for convenience.
    It does not check if the resulting mesh is still valid.

    Examples
    --------
    Consider the following points and one face definition and the resulting mesh.

    >>> points = [[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [1.0, 1.0, 0.0], [0.0, 1.0, 0.0], [0.5, 0.0, 0.0]]
    >>> faces = [[0, 1, 2, 3]]
    >>> mesh = Mesh.from_vertices_and_faces(points, faces)
    >>> mesh.face_degree(0)
    4
    >>> mesh.vertex_degree(4)
    0

    To add the isolated vertex to the single mesh face

    >>> mesh_add_vertex_to_face_edge(mesh, 4, 0, 0, 1)
    >>> mesh.face_degree(0)
    5
    >>> mesh.vertex_degree(4)
    2

    """
    vertices = mesh.face_vertices(fkey)
    i = vertices.index(v)
    u = vertices[i - 1]
    vertices.insert(key, i - 1)
    mesh.halfedge[u][key] = fkey
    mesh.halfedge[key][v] = fkey
    if u not in mesh.halfedge[key]:
        mesh.halfedge[key][u] = None
    if key not in mesh.halfedge[v]:
        mesh.halfedge[v][key] = None
    del mesh.halfedge[u][v]
    if u in mesh.halfedge[v]:
        del mesh.halfedge[v][u]
    if (u, v) in mesh.edgedata:
        del mesh.edgedata[u, v]
    if (v, u) in mesh.edgedata:
        del mesh.edgedata[v, u]


def split_volume_from_journal(citation_elements):
    """Split volume from journal title

    We need this because sometimes the volume is attached to the journal title
    instead of the volume. In those cases we move it here from the title to the
    volume
    """
    for el in citation_elements:
        if el['type'] == 'JOURNAL' and ';' in el['title']:
            el['title'], series = el['title'].rsplit(';', 1)
            el['volume'] = series + el['volume']
    return citation_elements


@classmethod
def getCurrentSession(cls):
    """Returns the current session, or ``None`` if no :class:`nose2.session.Session` is running.

        """
    return cls._currentSession


def view_ndof():
    """Use a 3D mouse device to pan/zoom the view

    """
    pass


def to_verbosity(string):
    """Converts the given verbosity to a number representing priority."""
    if string.lower().strip() == 'terse':
        return 1
    if string.lower().strip() == 'default':
        return 2
    if string.lower().strip() == 'verbose':
        return 3
    raise RuntimeError(f'Unknown verbosity level {string}.')


def psi_Ba_Na_Cl_PK74(T, P):
    """c-c'-a: barium sodium chloride [PK74]."""
    psi = 0.0
    valid = T == 298.15
    return psi, valid


def _iterate_response_terms(response):
    """Iterates over the terms in the given response"""
    for term in response['_embedded']['terms']:
        yield term


def getDmin(peaks):
    """needs a doc string"""
    return peaks[-1][-2]


def unique(input):
    """Returns the unique scalar elements in a tensor.

    Parameters
    ----------
    input : Tensor
        Must be a 1-D tensor.

    Returns
    -------
    Tensor
        A 1-D tensor containing unique elements.
    """
    pass


def _import(modname):
    """has_numpy, np = _import('numpy')
    >>> has_np, np = _import('numpy')
    """
    has_module = False
    try:
        imported_mod = __import__(modname)
        has_module = True
        return has_module, imported_mod
    except ImportError:
        has_module = False
        return has_module, None


def is_submodule_included(src, tgt):
    """Check that the tgt's submodule is included by src, if they belong
    to the same module."""
    if tgt is None or not hasattr(tgt, 'i_orig_module'):
        return True
    if (tgt.i_orig_module.keyword == 'submodule' and src.i_orig_module !=
        tgt.i_orig_module and src.i_orig_module.i_modulename == tgt.
        i_orig_module.i_modulename):
        if (src.i_orig_module.keyword == 'submodule' and src.i_orig_module.
            i_version != '1'):
            return True
        if src.i_orig_module.search_one('include', tgt.i_orig_module.arg
            ) is None:
            return False
    return True


def cam_com(exp, wellu, wellv, fieldx, fieldy, dxcoord, dycoord):
    """Add a field to the cam list.

    Return a list with parts for the cam command.
    """
    wellx = str(wellu + 1)
    welly = str(wellv + 1)
    fieldx = str(fieldx + 1)
    fieldy = str(fieldy + 1)
    return [('cmd', 'add'), ('tar', 'camlist'), ('exp', exp), ('ext', 'af'),
        ('slide', '0'), ('wellx', wellx), ('welly', welly), ('fieldx',
        fieldx), ('fieldy', fieldy), ('dxpos', str(dxcoord)), ('dypos', str
        (dycoord))]


def enable_com(wellu, wellv, fieldx, fieldy, enable):
    """Enable a field in a well.

    Return a list with parts for the cam command.
    """
    wellx = str(wellu + 1)
    welly = str(wellv + 1)
    fieldx = str(fieldx + 1)
    fieldy = str(fieldy + 1)
    return [('cmd', 'enable'), ('slide', '0'), ('wellx', wellx), ('welly',
        welly), ('fieldx', fieldx), ('fieldy', fieldy), ('value', str(
        enable).lower())]


def path_to_location(path):
    """Messages take a `repeated string` of path components."""
    if path.startswith('/'):
        path = path[1:]
    return path.split('/')


def _do_magick_convert_enlighten_border(width, height):
    """
    Build the command line arguments to enlighten the border in four regions.

    :param int width: The width of the image.
    :param int height: The height of the image.

    :return: Command line arguments for imagemagicks’ `convert`.
    :rtype: list
    """
    border = int(round((width + height) / 2 * 0.05))
    r = '{}x{}'.format(width - border, border), '{}x{}+{}'.format(border,
        height - border, width - border), '{}x{}+{}+{}'.format(width -
        border, border, border, height - border), '{}x{}+{}+{}'.format(border,
        height - border, 0, border)
    out = []
    for region in r:
        out += ['-region', region, '-level', '0%,30%']
    return out


def list_get_max_wordwidth(l):
    """
        l = ['a','bb','hello','xx','你好吗']
        list_get_max_wordwidth(l)
    """
    maxValueWidth = 0
    for each in l:
        eachValueWidth = each.__len__()
        if eachValueWidth > maxValueWidth:
            maxValueWidth = eachValueWidth
    return maxValueWidth


def jaccard(a, b):
    """Compute the Jaccard distance between two strings.

    :type a: str

    :type b: str

    :returns: float
    """
    if not a and not b:
        return 0
    n = len(a.intersection(b))
    return 1 - float(n) / (len(a) + len(b) - n)


@staticmethod
def _correct_formating(data: str):
    """
        Replacing all whitespaces with %20 (NameSilo requirement)
        :param data:

        :return: string
        """
    return data.replace(' ', '%20')


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


@staticmethod
def p_bit_mask(p):
    """bit_mask : BIT_MASK NUMERIC"""
    p[0] = p[2]


def check_in(choices, **params):
    """Checks parameters are in a list of allowed parameters
    Parameters
    ----------
    choices : array-like, accepted values
    params : object
        Named arguments, parameters to be checked
    Raises
    ------
    ValueError : unacceptable choice of parameters
    """
    for p in params:
        if params[p] not in choices:
            raise ValueError('{} value {} not recognized. Choose from {}'.
                format(p, params[p], choices))


def _get_attr_value(instance, attr, default=None):
    """
    Simple helper to get the value of an instance's attribute if it exists.

    If the instance attribute is callable it will be called and the result will
    be returned.

    Optionally accepts a default value to return if the attribute is missing.
    Defaults to `None`

    >>> class Foo(object):
    ...     bar = 'baz'
    ...     def hi(self):
    ...         return 'hi'
    >>> f = Foo()
    >>> _get_attr_value(f, 'bar')
    'baz'
    >>> _get_attr_value(f, 'xyz')

    >>> _get_attr_value(f, 'xyz', False)
    False
    >>> _get_attr_value(f, 'hi')
    'hi'
    """
    value = default
    if hasattr(instance, attr):
        value = getattr(instance, attr)
        if callable(value):
            value = value()
    return value


def set_prefs(prefs):
    """This function is called before opening the project"""
    prefs['ignored_resources'] = ['*.pyc', '*~', '.ropeproject', '.hg',
        '.svn', '_svn', '.git', '.tox', '.env', 'env', 'venv',
        'node_modules', 'bower_components']
    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 enableFaulthandler():
    """ Enable faulthandler for all threads.

    If the faulthandler package is available, this function disables and then
    re-enables fault handling for all threads (this is necessary to ensure any
    new threads are handled correctly), and returns True.

    If faulthandler is not available, then returns False.
    """
    try:
        import faulthandler
        faulthandler.disable()
        faulthandler.enable(all_threads=True)
        return True
    except ImportError:
        return False


def rotate(deg, x, y):
    """
    Generate an SVG transform statement representing rotation around a given
    point.
    """
    return 'rotate(%i %i %i)' % (deg, x, y)


def pos_s_2_bbox(pos, s):
    """
    from center_x,center_y,s to get bbox

    Parameters
    ----------
    pos , x, bbox
    s , int, bbox size

    Return:
        [x_min,y_min,x_max,y_max]
    """
    return [pos[0] - s / 2, pos[1] - s / 2, pos[0] + s / 2, pos[1] + s / 2]


def check_tuple_name(factor):
    """Opposite of check_rate_name - used to make sure the name is a flat name"""
    return '.'.join((factor.type,) + factor.name) if type(factor.name
        ) == tuple else factor


def virtual_residue_atoms(bg, s, i, strand=0):
    """
    Return the atoms for the virtual residue.

    :param bg: The BulgeGraph
    :param s: The stem
    :param i: The virtual residue number
    :param strand: The strand for which to get the virtual atoms
    """
    """
    if vpos == None or vvec == None:
        (vpos, vvec, vvec_l, vvec_r) = virtual_res_3d_pos(bg, s, i)
    if basis == None:
        basis = virtual_res_basis(bg, s, i, vvec).transpose()
    """
    if s[0] != 's':
        raise ValueError(
            'Expected stem (not single-stranded RNA element), got {}'.format(s)
            )
    glob_pos = bg.defines[s][0] + i, bg.defines[s][3] - i
    glob_pos = glob_pos[strand]
    return bg.virtual_atoms(glob_pos)


def dir_template_f(method_names: []) ->str:
    """
    generate `__dir__` method code to deliver
    a list of all methods which are mapped
    to an  API routes
    """
    method_names_ = "'" + "',\n            '".join(method_names) + "'"
    return f"""
    def __dir__(self):
        method_names = [
            {method_names_}
        ]
        return method_names
    """


def batch(proxy):
    """convenience method to get a batch proxy adapter"""
    return proxy._pyroBatch()


@classmethod
def _from_dict(cls, _dict):
    """Initialize a MessageContextGlobalSystem object from a json dictionary."""
    args = {}
    if 'timezone' in _dict:
        args['timezone'] = _dict.get('timezone')
    if 'user_id' in _dict:
        args['user_id'] = _dict.get('user_id')
    if 'turn_count' in _dict:
        args['turn_count'] = _dict.get('turn_count')
    return cls(**args)


def tupleize(element, ignore_types=(str, bytes)):
    """Cast a single element to a tuple."""
    if hasattr(element, '__iter__') and not isinstance(element, ignore_types):
        return element
    else:
        return tuple((element,))


def proba():
    """Retourne Bonjour nom """
    return 'Bonjour !'


@classmethod
def detect_invalidation(cls):
    """ Return True if a new invalidation is found in the table

        :rtype: Boolean
        """
    return cls.last_cache_id < cls.get_last_id()


def create_byte_match_set(Name=None, ChangeToken=None):
    """
    Creates a ByteMatchSet . You then use  UpdateByteMatchSet to identify the part of a web request that you want AWS WAF to inspect, such as the values of the User-Agent header or the query string. For example, you can create a ByteMatchSet that matches any requests with User-Agent headers that contain the string BadBot . You can then configure AWS WAF to reject those requests.
    To create and configure a ByteMatchSet , perform the following steps:
    For more information about how to use the AWS WAF API to allow or block HTTP requests, see the AWS WAF Developer Guide .
    See also: AWS API Documentation

    :example: response = client.create_byte_match_set(
        Name='string',
        ChangeToken='string'
    )

    :type Name: string
    :param Name: [REQUIRED]
            A friendly name or description of the ByteMatchSet . You can't change Name after you create a ByteMatchSet .

    :type ChangeToken: string
    :param ChangeToken: [REQUIRED]
            The value returned by the most recent call to GetChangeToken .

    :rtype: dict
    :return: {
        'ByteMatchSet': {
            'ByteMatchSetId': 'string',
            'Name': 'string',
            'ByteMatchTuples': [
                {
                    'FieldToMatch': {
                        'Type': 'URI'|'QUERY_STRING'|'HEADER'|'METHOD'|'BODY',
                        'Data': 'string'
                    },
                    'TargetString': b'bytes',
                    'TextTransformation': 'NONE'|'COMPRESS_WHITE_SPACE'|'HTML_ENTITY_DECODE'|'LOWERCASE'|'CMD_LINE'|'URL_DECODE',
                    'PositionalConstraint': 'EXACTLY'|'STARTS_WITH'|'ENDS_WITH'|'CONTAINS'|'CONTAINS_WORD'
                },
            ]
        },
        'ChangeToken': 'string'
    }

    :returns:
    Name (string) -- [REQUIRED]
    A friendly name or description of the  ByteMatchSet . You can't change Name after you create a ByteMatchSet .

    ChangeToken (string) -- [REQUIRED]
    The value returned by the most recent call to  GetChangeToken .

    """
    pass


def add_transaction(cursor, tid, username, description, extension, packed=False
    ):
    """Add a transaction."""


def display_dashboard(height, unique_name=None):
    """
    Once a case study has been submitted:
    * Obtain the parameters
    * Obtain the scenarios and parameter values
    * Create a display area for controls, with:
      - A dropdown to select scenarios
      - A control per parameter
      - A "recalculate" button
      - A view per dataset of intereset
        - pivottablejs. from pivottablejs import pivot_ui, pivot_ui(<dataframe>)
    """
    pass


@staticmethod
def bind(obj, trait_name, extension_point_id):
    """ Create a binding to an extension point. """
    from .extension_point_binding import bind_extension_point
    return bind_extension_point(obj, trait_name, extension_point_id)


def is_applied(migrations_applied, migration_name):
    """ Check if a migration we want to run is already in the list of applied migrations """
    return [(True) for migration in migrations_applied if migration['name'] ==
        migration_name]


def rotate_z(vector, theta):
    """ Rotate a 3D vector about the +z axis
        Inputs:
            vector: 3d vector array
            theta [rad]: angle to rotate the vector about
        Returns: rotated vector
    """
    import numpy as np
    R = np.array([[np.cos(theta), -np.sin(theta), 0], [np.sin(theta), np.
        cos(theta), 0], [0, 0, 1]])
    if np.ndim(vector) == 1:
        out = np.zeros(3)
        out[0] = R[0, 0] * vector[0] + R[0, 1] * vector[1] + R[0, 2] * vector[2
            ]
        out[1] = R[1, 0] * vector[0] + R[1, 1] * vector[1] + R[1, 2] * vector[2
            ]
        out[2] = R[2, 0] * vector[0] + R[2, 1] * vector[1] + R[2, 2] * vector[2
            ]
    else:
        out = np.zeros((3, vector.shape[1]))
        out[0] = R[0, 0] * vector[(0), :] + R[0, 1] * vector[(1), :] + R[0, 2
            ] * vector[(2), :]
        out[1] = R[1, 0] * vector[(0), :] + R[1, 1] * vector[(1), :] + R[1, 2
            ] * vector[(2), :]
        out[2] = R[2, 0] * vector[(0), :] + R[2, 1] * vector[(1), :] + R[2, 2
            ] * vector[(2), :]
    return out


def convert_outer_to_inner_nodes(clusters: dict, internal_node_map: dict):
    """
    Find the lowest common ancestor (internal node) for all leaves in the range.
    This is only necessary if the original nodes parsed from the colours_style.txt file were leaves.
    :param clusters: A dictionary mapping start and end leaves of a clade for a single marker's colours_style.txt layer
    :param internal_node_map: A dictionary mapping each internal node to a list of all of its descendent leaves
    :return:
    """
    leaf_annotation_map = dict()
    for cluster in clusters.keys():
        if cluster not in leaf_annotation_map:
            leaf_annotation_map[cluster] = list()
        for frond_tips in clusters[cluster]:
            start, end = frond_tips
            warm_front = dict()
            for inode in internal_node_map:
                clade = internal_node_map[inode]
                if start in clade:
                    warm_front[inode] = clade
            for inode in sorted(warm_front, key=lambda x: len(warm_front[x])):
                if end in warm_front[inode]:
                    leaf_annotation_map[cluster].append((inode, inode))
                    break
    return leaf_annotation_map