def simplify_to_UDlextag(conllulexF):
    """
    Given a .conllulex file (or iterable over lines), clear the 8 columns
    containing MWE and supersense information, leaving only the full lextag
    column at the end.
    """
    result = ''
    for ln in conllulexF:
        row = ln.strip()
        if row and not row.startswith('#'):
            row = row.split('\t')
            row[10:18] = [''] * 8
            row = '\t'.join(row)
        result += row + '\n'
    return result


def resolveRelationshipTokens(tokens):
    """Returns an iterable of relations for the tokens given"""


def get_url(context):
    """ Return a redirection URL """


def create_libname(signature, cache_params):
    """Create library name based on signature and params,
    without path, prefix 'lib', or extension '.so'."""
    return cache_params['lib_basename'] + signature


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

        :param SsoChangeLoginUrlType val:
        :rtype: EventType
        """
    return cls('sso_change_login_url', val)


def e2rel(e):
    """turns NER tags into common words"""
    if e == 'MISC':
        return 'entity'
    return e.lower()


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


def sample():
    """Add keyframes on every frame between the selected keyframes

    """
    pass


def dec_separation(v1, v2):
    """Returns difference in declination between two CelestialVectors."""
    return v1.dec - v2.dec


def asynchronous(resource):
    """Instructs a decorated resource that it is to be asynchronous.

    An asynchronous resource means that `response.close()` must be called
    explicitly as returning from a method (eg. `get`) does not close
    the connection.

    @note
        This can also be configured by setting `asynchronous` to `True`
        on `<resource>.Meta`. The benefit of the decorator is that this
        can be applied to specific methods as well as the entire class
        body.
    """
    resource.meta.asynchronous = True
    return resource


def _weekday_test(date, kwargs):
    """
    Computes weekly indicators.
    """
    if 'weekday' in kwargs:
        weekday = kwargs['weekday']
        if date.weekday() == weekday:
            return 1
        else:
            return 0
    else:
        return date.weekday()


def _paint(art, positions, characters):
    """Paint characters into their positions in the art.

    Args:
        art: the 2D list of str representing the art.
        positions: list of (x, y) with same size as characters.
        characters: list of str with same size as positions.

    Returns:
        modified art - 2D list of str.
    """
    for position, character in zip(positions, characters):
        art[int(position[0])][int(position[1])] = character
    return art


def get_intersection(l1, l2):
    """ Finds the intersection of 2 lists including common duplicates"""
    intersection_set = set(l1).intersection(set(l2))
    intersection_list = []
    for i in intersection_set:
        num = min(l1.count(i), l2.count(i))
        for j in range(num):
            intersection_list.append(i)
    return intersection_list


def to_boolean(obj) ->bool:
    """
    Convert any of the common wire representations of a ``bool`` to a ``bool``.
    """
    if obj is None:
        return None
    if isinstance(obj, bool):
        return obj
    elif isinstance(obj, str):
        lobj = obj.lower().strip()
        if lobj == 'true':
            return True
        elif lobj == 'false':
            return False
        else:
            raise ValueError(f'Could not parse a string as a boolean: {obj!r}')
    raise ValueError(f'Could not parse as a boolean: {obj!r}')


def isValid():
    """ Returns true if (self.getModifiedTime() + self.getTimeout())
        is greater than the current time.time() value. """


def psi_Ca_Na_CO3_HMW84(T, P):
    """c-c'-a: calcium sodium carbonate [HMW84]."""
    psi = 0.0
    valid = T == 298.15
    return psi, valid


def find_user(user_name, source):
    """
    Search for a user by name on the given object
    """
    name = user_name.lower()
    for user in source.users:
        if user.nickname.lower() == name:
            return user
    return None


def matchPrefix(text):
    """
    This is silver bullet, cornerstone and magic wand of speed of this algorithm
    it filters patterns using manually selected rules. Yes, yes, it's "dirty" code and it could be beautified in
    many ways but this library intended to be fast, not beautiful. Without matching is x1.3 slower so let it be.
    :param text: text with date to match
    :return: list of patterns to run against
    """
    basekeys = []
    if not text[0].isdigit():
        if ord(text[0].lower()) in range(ord('a'), ord('z') + 1):
            basekeys = ['dt:date:eng1', 'dt:date:date_eng1x',
                'dt:date:eng3', 'dt:date:date_eng2_lc', 'dt:date:date_eng2',
                'dt:date:date_eng2_short', 'dt:date:date_eng3',
                'dt:date:weekday_eng', 'dt:date:weekday_eng_lc',
                'dt:date:weekday_eng_wshort', 'dt:date:weekday_eng_iso',
                'dt:date:weekday_short_eng_iso', 'dt:date:fr_base_article',
                'dt:date:fr_base_lc_article',
                'dt:date:weekday_eng_mshort_wshort']
            basekeys += ['dt:date:pt_base', 'dt:date:pt_base_lc',
                'dt:date:pt_base_article', 'dt:date:pt_base_lc_article']
            basekeys += ['dt:date:es_base', 'dt:date:es_base_lc',
                'dt:date:es_base_article', 'dt:date:es_base_lc_article',
                'dt:date:es_rare_1', 'dt:date:es_rare_2']
            basekeys += ['dt:date:it_base', 'dt:date:it_base_lc',
                'dt:date:it_base_article', 'dt:date:it_base_lc_article',
                'dt:date:it_rare_1', 'dt:date:it_rare_2']
        else:
            basekeys = ['dt:date:weekday_rus', 'dt:date:weekday_rus_lc1',
                'dt:date:rare_5', 'dt:date:rare_6']
    elif text[1] == '.' or text[2] == '.':
        basekeys = ['dt:date:date_2', 'dt:date:date_4', 'dt:date:date_rus3',
            'dt:date:date_4_point', 'dt:date:date_eng1', 'dt:date:noyear_1',
            'dt:date:rare_2', 'dt:date:rare_3']
        basekeys += ['dt:date:de_base', 'dt:date:de_base_lc']
    elif text[1] == ',' or text[2] == ',':
        basekeys = ['dt:date:date_rus']
    elif text[1] == '/' or text[2] == '/':
        basekeys = ['dt:date:date_1', 'dt:date:date_9', 'dt:date:date_8',
            'dt:date:date_usa', 'dt:date:date_usa_1', 'dt:date:rare_1']
    elif text[1] == '-' or text[2] == '-':
        basekeys = ['dt:date:date_iso8601', 'dt:date:date_iso8601_short']
    elif text[4] == '-':
        basekeys = ['dt:date:date_iso8601', 'dt:date:date_9']
    elif text[4] == '.':
        basekeys = ['dt:date:date_10']
    else:
        basekeys = ['dt:date:date_3', 'dt:date:date_5', 'dt:date:date_6',
            'dt:date:date_7', 'dt:date:date_rus', 'dt:date:date_rus2',
            'dt:date:date_rus_lc1', 'dt:date:date_rus_lc2',
            'dt:date:date_eng1', 'dt:date:date_eng1_short',
            'dt:date:date_eng1_lc', 'dt:date:date_eng1xx']
        basekeys += ['dt:date:date_1', 'dt:date:date_9', 'dt:date:date_8',
            'dt:date:date_usa', 'dt:date:date_usa_1', 'dt:date:rare_1',
            'dt:date:rare_2', 'dt:date:rare_3', 'dt:date:rare_4',
            'dt:date:date_5', 'dt:date:fr_base', 'dt:date:fr_base_lc']
        basekeys += ['dt:date:pt_base_article',
            'dt:date:pt_base_lc_article', 'dt:date:pt_base',
            'dt:date:pt_base_lc']
        basekeys += ['dt:date:de_base', 'dt:date:de_base_lc']
        basekeys += ['dt:date:bg_base', 'dt:date:bg_base_lc']
        basekeys += ['dt:date:es_base', 'dt:date:es_base_lc',
            'dt:date:es_base_article', 'dt:date:es_base_lc_article']
        basekeys += ['dt:date:it_base', 'dt:date:it_base_lc',
            'dt:date:it_base_article', 'dt:date:it_base_lc_article']
    return basekeys


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 int_set_null(int_value):
    """sql util function"""
    return 'null' if int_value is None else str(int_value)


def parseBoolValue(value, fail_on_errors=True, preserve_none=False):
    """Parses a string representing bool value. If parsing was successful,
       returns True or False. If preserve_none=True, returns True, False,
       or None. If parsing was not successful, raises  ValueError, or, if
       fail_on_errors=False, returns None."""
    if not isinstance(value, str):
        if preserve_none and value is None:
            return value
        return bool(value)
    elif preserve_none and value.lower() == 'none':
        return None
    elif value.lower() in ('true', 'yes', 'y', 'on', '1'):
        return True
    elif value.lower() in ('false', 'no', 'n', 'off', '0', 'none'):
        return False
    elif fail_on_errors:
        raise ValueError('Cannot parse bool value: %r' % value)


def _make_init_cond(metabolite_str):
    """Format metabolite identifier to match initial condition accesors.

    Warnings
    --------
    This method is intended for internal use only.

    """
    return 'init(' + metabolite_str + ')'


def editPost(postid, username, password, struct, publish):
    """Implement MetaWeblog editPost.
        """


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


def leapYear(year):
    """Most common first.

    >>> leapYear(1956)
    True
    >>> leapYear(1957)
    False
    >>> leapYear(1900) # No leapday on century crossings.
    False
    >>> leapYear(2000) # But there is a leapday on millennium crossings.
    True
    """
    if year % 4 != 0:
        return False
    if year % 400 == 0:
        return True
    if year % 100 == 0:
        return False
    return True


def format_code_block(code, language='python'):
    """format a chunk of code (usually a dictionary) into a code block.
    """
    return '```%s\n%s\n```' % (language, code)


def processEscapes(text, restore=False):
    """
    Parameter:  String (unicode or bytes).
    Returns:    The `text`, with after processing the following backslash
                escape sequences. This is useful if you want to force a "dumb"
                quote or other character to appear.

                Escape  Value
                ------  -----
                \\\\      \
                \\"      "
                \\'      '
                \\.      .
                \\-      -
                \\`      `
    """
    replacements = ('\\\\', '\'), ('\\"', '"'), ("\\'", '''), (
        '\\.', '.'), ('\\-', '-'), ('\\`', '`')
    if restore:
        for ch, rep in replacements:
            text = text.replace(rep, ch[1])
    else:
        for ch, rep in replacements:
            text = text.replace(ch, rep)
    return text


@classmethod
def remove_room_member(cls, room_id: int, user_id: int) ->None:
    """Remove a room member who left stored in a room.

        :param room_id: The room's ID the user left from
        :type room_id: int
        :param user_id: The ID of the user who left
        :type user_id: int
        """
    member = cls.rooms[room_id].members[user_id]
    cls.rooms[room_id].members.pop(user_id)
    if cls.member_changes['left'].get(room_id) is None:
        cls.member_changes['left'][room_id] = cls.rooms[room_id]
    cls.member_changes['left'][room_id]._members_left[user_id] = member


def gcd(num_a, num_b):
    """Calculates the greatest common divisor.

  Non-recursive fast implementation.

  :param num_a:
      Long value.
  :param num_b:
      Long value.
  :returns:
      Greatest common divisor.
  """
    num_a, num_b = max(num_a, num_b), min(num_a, num_b)
    while num_b:
        num_a, num_b = num_b, num_a % num_b
    return num_a


def probability_to_odds(prob):
    """Converts given probability (proportion) to odds

    Probability is converted to odds using

    .. math::

        O = \\frac{\\Pr}{1 - \\Pr}

    Parameters
    ---------------
    prob : float, NumPy array
        Probability or array of probabilities to transform into odds

    Returns
    ----------
    odds
        Float or array of odds

    Examples
    --------
    Convert a single probability to an odds

    >>> from zepid.calc import probability_to_odds
    >>> probability_to_odds(0.3)

    Convert an array of probabilities to odds

    >>> import numpy as np
    >>> probs = np.array([0.3, 0.1, 0.2, 0.5, 0.01])
    >>> probability_to_odds(probs)
    """
    return prob / (1 - prob)


def is_unique(seq):
    """Returns True if every item in the seq is unique, False otherwise."""
    try:
        s = set(seq)
        return len(s) == len(seq)
    except TypeError:
        buf = []
        for item in seq:
            if item in buf:
                return False
            buf.append(item)
        return True


def match_tag_to_name(name, mapping):
    """
    Try to match given name to mergefield tag defined in mapping dict
    Not case sensitive
    :param name: str
    :param mapping: dict
    :return: str: Tag
    """
    for tag, fieldname in mapping.items():
        if str(name).lower() == str(fieldname).lower():
            return tag


def metronixName(ext: str, sensor: str, serial: int, chopper: bool) ->str:
    """Get Metronix calibration file name

    Parameters
    ----------
    ext : str
        Calibration file extension
    sensor : str
        Sensor name
    serial : int
        The sensor serial number
    chopper : bool
        Boolean flag for chopper on or off

    Returns
    -------
    out : str
        Name of calibration file
    """
    if sensor == '' and not serial > 0:
        return None
    return '{}{}.{}'.format(sensor, serial, ext)


def get_uri_parent(uri):
    """Return URI of parent collection with trailing '/', or None, if URI is top-level.

    This function simply strips the last segment. It does not test, if the
    target is a 'collection', or even exists.
    """
    if not uri or uri.strip() == '/':
        return None
    return uri.rstrip('/').rsplit('/', 1)[0] + '/'


def getfirst(iterable, exception=KeyError):
    """Get the first item from an iterable.
	This also works for generators.
	If the iterable is empty, exception is raised.
	If exception is None, None is returned instead.
	Warning: If iterable is not indexable (for example a set),
		 an arbitrary item is returned instead.
	"""
    try:
        return next(iter(iterable))
    except StopIteration:
        if exception:
            raise exception
        return None


@classmethod
def register_type_post_resources_template(cls, project, template):
    """Hook to register custom resources in the post_resources template.
        This template is applied after the resources stack.
        Note: This hook will be only executed once per resource type."""
    pass


def p_tracktype(t):
    """tracktype : AUDIO
                 | CDG
                 | MODE
                 | CDI"""
    t[0] = t[1]


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 convert_py_namespace_to_cpp_header_def(python_namespace):
    """Convert a Python namespace into a C++ header def token.

    Parameters
    ----------
    python_namespace : `str`
        A string describing a Python namespace. For example,
        ``'lsst.example'``.

    Returns
    -------
    cpp_header_def : `str`
        C++ header def, such as '`'LSST_EXAMPLE_H'``.
    """
    return python_namespace.upper().replace('.', '_') + '_H'


def _thread_done(gt, *args, **kwargs):
    """Callback function to be passed to GreenThread.link() when we spawn()
    Calls the :class:`ThreadGroup` to notify if.

    """
    kwargs['group'].thread_done(kwargs['thread'])


@classmethod
def from_lines(cls, lines, grid=None, active_area=None, isfr=None, model=
    None, model_length_units='undefined', minimum_reach_length=None,
    cull_flowlines_to_active_area=True, consolidate_conductance=False,
    one_reach_per_cell=False, model_name=None, **kwargs):
    """
        Create an instance of Riv from an SFRmaker.lines object.

        Parameters
        ----------
        lines : SFRmaker.lines instance :
        grid :
        active_area :
        isfr :
        model :
        model_length_units :
        minimum_reach_length :
        cull_flowlines_to_active_area :
        consolidate_conductance :
        one_reach_per_cell :
        model_name :
        kwargs :

        Returns
        -------
        riv : SFRmaker.RivData instance
        """
    raise NotImplementedError('from_lines not implemented yet.')


@staticmethod
def grant_privileges_commands(rolename: str, schema: str, read_write: bool
    ) ->list:
    """Creates commands for granting privileges for accessing database objects to a role/user"""
    x_role = '"' + rolename + '"'
    x_schema = '"' + schema + '"'
    statements = list()
    statements.append(' '.join(['GRANT USAGE ON SCHEMA', x_schema, 'TO',
        x_role]))
    statements.append(' '.join(['GRANT SELECT ON ALL SEQUENCES IN SCHEMA',
        x_schema, 'TO', x_role]))
    statements.append(' '.join(['GRANT SELECT ON ALL TABLES IN SCHEMA',
        x_schema, 'TO', x_role]))
    if read_write:
        statements.append(' '.join([
            'GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA', x_schema, 'TO',
            x_role]))
        statements.append(' '.join([
            'GRANT USAGE ON ALL SEQUENCES IN SCHEMA', x_schema, 'TO', x_role]))
        statements.append(' '.join(['GRANT INSERT ON ALL TABLES IN SCHEMA',
            x_schema, 'TO', x_role]))
        if not schema.startswith('audit'):
            statements.append(' '.join([
                'GRANT UPDATE ON ALL TABLES IN SCHEMA', x_schema, 'TO',
                x_role]))
            statements.append(' '.join([
                'GRANT DELETE ON ALL TABLES IN SCHEMA', x_schema, 'TO',
                x_role]))
    return statements


def normalize_text(string):
    """ Normalize spaces and newlines
    >>> normalize_text("\\nHello   world  \\t\\n!")
    'Hello world!'
    """
    return ' '.join(string.split())


def collection_exclude_clear():
    """Include collection in the active view layer

    """
    pass


def generate_jekyll_config(path, site_title):
    """Builds a jekyll site configuration file."""
    cf = open(path + '/_config.yml', 'w')
    cf.write('name: ' + site_title + '\n')
    cf.write('paginate: 7\n')
    cf.close()


def compose(*funcs):
    """
    Returns the function composition of two functions.

    Args:
        funcs ([function]): Each function should have exactly one argument.

    Returns:
        x |-> (f o g o ... o h)(x)

    """

    def fog(arg):
        for f in funcs:
            arg = f(arg)
        return arg
    return


@classmethod
def detect(cls, stream):
    """Detect the file format given a filename.
        Return True if a stream is this file format.

        .. versionchanged:: 0.9.0
            Changed from a static method to a class method.
        """
    raise NotImplementedError('Must implement a "detect" class method.')


def remove_cookie_by_name(cookiejar, name, domain=None, path=None):
    """Unsets a cookie by name, by default over all domains and paths.

    Wraps CookieJar.clear(), is O(n).
    """
    clearables = []
    for cookie in cookiejar:
        if cookie.name != name:
            continue
        if domain is not None and domain != cookie.domain:
            continue
        if path is not None and path != cookie.path:
            continue
        clearables.append((cookie.domain, cookie.path, cookie.name))
    for domain, path, name in clearables:
        cookiejar.clear(domain, path, name)


def vert_separate(vert: 'bmesh.types.BMVert', edges: 'bmesh.types.BMEdge'
    ) ->'bmesh.types.BMVert':
    """Separate this vertex at every edge.

    :param vert: The vert to be separated.
    :type vert: 'bmesh.types.BMVert'
    :param edges: The edges to separated.
    :type edges: 'bmesh.types.BMEdge'
    :return:  The newly separated verts (including the vertex passed).
    """
    pass


def graph_delete_knot():
    """Delete curve knots

    """
    pass


def dependent_keys(tasks, complete=False):
    """
    All keys that need to compute for these keys to finish.

    If *complete* is false, omit tasks that are busy processing or
    have finished executing.
    """
    out = set()
    errors = set()
    stack = list(tasks)
    while stack:
        ts = stack.pop()
        key = ts.key
        if key in out:
            continue
        if not complete and ts.who_has:
            continue
        if ts.exception is not None:
            errors.add(key)
            if not complete:
                continue
        out.add(key)
        stack.extend(ts.dependencies)
    return out, errors


def psi_Ca_Cl_NO3_PK74(T, P):
    """c-a-a': calcium chloride nitrate [PK74]."""
    psi = -0.017
    valid = T == 298.15
    return psi, valid


def get_page_filename(page_path: str) ->str:
    """Generate a filename for a rendered page."""
    return f'{page_path}.j2'


def get_distribution_names(namespace_pairs, rv_base_class):
    """
    Collect names of statistical distributions and their generators.

    Parameters
    ----------
    namespace_pairs : sequence
        A snapshot of (name, value) pairs in the namespace of a module.
    rv_base_class : class
        The base class of random variable generator classes in a module.

    Returns
    -------
    distn_names : list of strings
        Names of the statistical distributions.
    distn_gen_names : list of strings
        Names of the generators of the statistical distributions.
        Note that these are not simply the names of the statistical
        distributions, with a _gen suffix added.

    """
    distn_names = []
    distn_gen_names = []
    for name, value in namespace_pairs:
        if name.startswith('_'):
            continue
        if name.endswith('_gen') and issubclass(value, rv_base_class):
            distn_gen_names.append(name)
        if isinstance(value, rv_base_class):
            distn_names.append(name)
    return distn_names, distn_gen_names


def swap_columns(data, swapCols):
    """function to swap a set of column pairs in the data array"""
    for z in data:
        for swap in swapCols:
            z[swap[0]], z[swap[1]] = z[swap[1]], z[swap[0]]


def getArticles(**kwargs):
    """ Returns a list of articles (catalog brains)
        """


def _get_start_end_row(A, nrows):
    """Find the starting and ending points of the matrix"""
    istart = None
    for irow in range(nrows):
        if abs(A[irow]) > 0.0:
            istart = irow
            break
    iend = None
    for irow in reversed(range(nrows)):
        if abs(A[irow]) > 0.0:
            iend = irow
            break
    return istart, iend


def encode_edd25519_xmr_const(arr):
    """
    Converts Monero based ed25519 constants to int32_t constants

    :param arr:
    :return:
    """
    bits = [26, 25, 26, 25, 26, 25, 26, 25, 26, 25]
    limbs = []
    c = 0
    for i, x in enumerate(arr):
        r = x + c
        if x < 0:
            r = r + (1 << bits[i])
            c = x >> bits[i]
        else:
            c = 0
        limbs.append(r)
    return limbs


def keyconfig_import(filepath: str='keymap.py', filter_folder: bool=True,
    filter_text: bool=True, filter_python: bool=True, keep_original: bool=True
    ):
    """Import key configuration from a python script

    :param filepath: filepath
    :type filepath: str
    :param filter_folder: Filter folders
    :type filter_folder: bool
    :param filter_text: Filter text
    :type filter_text: bool
    :param filter_python: Filter python
    :type filter_python: bool
    :param keep_original: Keep original, Keep original file after copying to configuration folder
    :type keep_original: bool
    """
    pass


def get_incomplete_elements(cg):
    """
    Get an estimated list of cg-elements which have missing residues in the PDB.

    One of many problems with PDB data are residues, for which no
    coordinates could be determined experimentally. This function gives
    an estimated list of cg-elements, which are affected by missing residues.
    """
    incomplete = set()
    for elem in cg.defines:
        for r in cg.define_range_iterator(elem, adjacent=elem[0] != 's'):
            if cg.seq[r[0]:r[1]] != cg.seq.with_missing[r[0]:r[1]]:
                incomplete.add(elem)
    return incomplete


@classmethod
def from_rules(cls, rules, policy=None):
    """
        Construct a SAT solver from a rules generator.

        Parameters
        ----------
        rules: RulesGenerator
        policy: IPolicy
            The policy to use for this SAT solver.

        Returns
        -------
        solver: MiniSATSolver.

        """
    solver = cls(policy)
    for rule in rules:
        solver.add_clause(rule.literals, rule=rule)
    solver._setup_assignments()
    return solver


@staticmethod
def to_kelvin(delisle):
    """ Convert delisle to kelvin """
    return 373.15 - delisle * 2 / 3


def mysql_large_prefix_check(engine):
    """Check mysql has innodb_large_prefix set"""
    if not str(engine.url).startswith('mysql'):
        return False
    variables = dict(engine.execute(
        'show variables where variable_name like "innodb_large_prefix" or variable_name like "innodb_file_format";'
        ).fetchall())
    if variables['innodb_file_format'] == 'Barracuda' and variables[
        'innodb_large_prefix'] == 'ON':
        return True
    else:
        return False


def raise_exception(exception):
    """Raises an exception. For use in expressions."""
    raise exception


def create_msb_table_individual(poly, width):
    """ Generate a CRC table calculating each entry.
        Mainly for demonstration and test, since calculate_msb_table() is
        much more efficient at calculating the same information
    :return: Generated table
    """
    msb_lshift = width - 8
    ms_bit = 1 << width - 1
    result_mask = (1 << width) - 1
    table = 256 * [0]
    for n in range(1, 256):
        crc = n << msb_lshift
        for _ in range(8):
            if crc & ms_bit:
                crc = crc << 1 ^ poly
            else:
                crc <<= 1
        table[n] = crc & result_mask
    return table


def lookupMailRename(name, timeout=None):
    """
        Perform an MR record lookup.

        @type name: C{str}
        @param name: DNS name to resolve.

        @type timeout: Sequence of C{int}
        @param timeout: Number of seconds after which to reissue the query.
            When the last timeout expires, the query is considered failed.

        @rtype: L{Deferred}
        @return: A L{Deferred} which fires with a three-tuple of lists of
            L{twisted.names.dns.RRHeader} instances.  The first element of the
            tuple gives answers.  The second element of the tuple gives
            authorities.  The third element of the tuple gives additional
            information.  The L{Deferred} may instead fail with one of the
            exceptions defined in L{twisted.names.error} or with
            C{NotImplementedError}.
        """


def calculate_unladen_mass(curb_mass, fuel_mass):
    """
    Calculate unladen mass [kg].

    :param curb_mass:
        Curb mass [kg].
    :type curb_mass: float

    :param fuel_mass:
        Fuel mass [kg].
    :type fuel_mass: float

    :return:
        Unladen mass [kg].
    :rtype: float
    """
    return curb_mass + fuel_mass


@staticmethod
def _find_peer_nbs(nb_wraps, nb, include_self=False):
    """Finds all of the peer (same vSwitch) Network Bridges.

        :param nb_wraps: List of pypowervm NetBridge wrappers.
        :param nb: The NetBridge to find.
        :param include_self: (Optional, Default False) If set to true, will
                             include the nb in the response list.
        :return: List of Network Bridges on the same vSwitch as the seed.  Does
                 not include the nb element.
        """
    vs_search_id = nb.seas[0].primary_adpt.vswitch_id
    ret = []
    for nb_elem in nb_wraps:
        if nb.uuid == nb_elem.uuid and not include_self:
            continue
        other_vs_id = nb_elem.seas[0].primary_adpt.vswitch_id
        if other_vs_id == vs_search_id:
            ret.append(nb_elem)
    return ret


def ensure_trailing_slash(path):
    """Return path if path ends with a / or path + / if it doesn't."""
    return path if path.endswith('/') else path + '/'


@classmethod
def _add_init_parser(cls, subparsers, handler):
    """Creates a subparser for the init command

        Args:
            subparsers (argparse._SubParsersAction): Subparsers
            handler (function): Handler for init command
        """
    init_parser = subparsers.add_parser('init', description=
        "Creates a '.gisreprc' configuration file to store Github username and adds the password to the system password manager."
        , help='Initialise gisrep to use Github credentials')
    init_parser.add_argument('-f', '--force', action='store_true', help=
        'Overwrite an existing config file')
    init_parser.add_argument('-l', '--local', help=
        'Path to a directory in which to save the file')
    init_parser.set_defaults(handler=handler)


@classmethod
def set_handler(cls, handler):
    """ Set Lambda handler for server.

            :param function handler: Lambda handler function
        """
    cls.handler = handler


def get_resource_and_action(action, pluralized=None):
    """Return resource and enforce_attr_based_check(boolean).

    It is per resource and action extracted from api operation.
    """
    data = action.split(':', 1)[0].split('_', 1)
    resource = pluralized or '%ss' % data[-1]
    enforce_attr_based_check = data[0] not in ('get', 'delete')
    return resource, enforce_attr_based_check


@staticmethod
def _correct_corr(R, n, k):
    """Corrige la correlacion por cantidad de parametros.

        Args:
            R (float): Correlacion
            n (int): Cantidad de datos
            k (int): Cantidad de parametros
        Returns:
            corrected (float): El valor corregido de R
        """
    try:
        corrected = 1 - (1 - R ** 2) * float(n - 1) / (n - k - 1)
    except:
        corrected = None
    return corrected


@staticmethod
def color_message(text, color='#1433b1'):
    """
        Puts BB-Code formatting around the provided text.

        :param text: text which should be colored.
        :param color: the color which should be put on the text.
        :return: color BB-code formatted string.
        """
    return f'[color={color}]{text}[/color]'


def __call__(context):
    """Returns a default value for the field."""


def local_uri_to_path(uri):
    """
    Convert URI to local filesystem path.
    """
    from six.moves import urllib
    path = urllib.parse.urlparse(uri).path if uri.startswith('file:') else uri
    return urllib.request.url2pathname(path)


def get_config(args):
    """Loads AWS Config profiles (not credentials) from JSON file / url.

    .. todo::
        everything

    ``qrmr get-config https://example.com/dev_config.json``

    Retrieves a JSON file or url with AWS Config profiles allowing AWS IAM
    Assume Role operations.

    The ``~/.aws/credentials`` file should contain only `credential` profiles,
    while the ``~/.aws/config`` file should only contain `config` profiles with
    which one can role assume into other AWS accounts.

    You need to have your environments set up according to the AWS Well-Architected
    Framework meaning: a central AWS account with all IAM Users and AssumeRole
    permissions to other accounts, other accounts with IAM Roles with TrustRelationships
    to the central AssumeRole roles.

    This QRMR function allows you to publish a JSON file with config profiles
    for different teams to ease setup and changes in IAM setup and terminal usage.

    .. seealso::
        well-arch framework
    """
    pass


def water(target, temperature='pore.temperature', salinity='pore.salinity'):
    """
    Calculates viscosity of pure water or seawater at atmospheric pressure
    using Eq. (22) given by Sharqawy et. al [1]. Values at temperature higher
    than the normal boiling temperature are calculated at the saturation
    pressure.

    Parameters
    ----------
    target : OpenPNM Object
        The object for which these values are being calculated. This
        controls the length of the calculated array, and also provides
        access to other necessary thermofluid properties.

    temperature : string
        The dictionary key containing the temperature values. Temperature must
        be in Kelvin for this emperical equation to work. Can be either a pore
        or throat array.

    salinity : string
        The dictionary key containing the salinity values. Salinity must be
        expressed in g of salt per kg of solution (ppt). Can be either a
        pore or throat array, but must be consistent with ``temperature``.

    Returns
    -------
    value : NumPy ndarray
        Array containing viscosity of water/seawater in [kg/m.s]

    Notes
    -----
     T must be in K, and S in g of salt per kg of phase, or ppt (parts per
        thousand)
    VALIDITY: 273 < T < 453 K; 0 < S < 150 g/kg;
    ACCURACY: 1.5 %

    References
    ----------
    [1] Sharqawy M. H., Lienhard J. H., and Zubair, S. M., Desalination and
        Water Treatment, 2010.

    """
    T = target[temperature]
    if salinity in target.keys():
        S = target[salinity]
    else:
        S = 0
    TC = T - 273.15
    S = S / 1000
    a1 = 0.15700386464
    a2 = 64.99262005
    a3 = -91.296496657
    a4 = 4.2844324477e-05
    mu_w = a4 + 1 / (a1 * (TC + a2) ** 2 + a3)
    a5 = 1.540913604
    a6 = 0.019981117208
    a7 = -9.5203865864e-05
    a8 = 7.9739318223
    a9 = -0.075614568881
    a10 = 0.00047237011074
    A = a5 + a6 * T + a7 * T ** 2
    B = a8 + a9 * T + a10 * T ** 2
    mu_sw = mu_w * (1 + A * S + B * S ** 2)
    value = mu_sw
    return value


@classmethod
def fromvars(cls, dataset, batch_size, train=None, **kwargs):
    """Create a Batch directly from a number of Variables."""
    batch = cls()
    batch.batch_size = batch_size
    batch.dataset = dataset
    batch.fields = dataset.fields.keys()
    for k, v in kwargs.items():
        setattr(batch, k, v)
    return batch


def url_basename(url, content_type):
    """Return best-guess basename from URL and content-type.

    >>> from django_downloadview.utils import url_basename

    If URL contains extension, it is kept as-is.

    >>> print(url_basename(u'/path/to/somefile.rst', 'text/plain'))
    somefile.rst

    """
    return url.split('/')[-1]


def packed_drop_first(sequences, batch_sizes):
    """
    Drops the first item of each sequence in the given data according to the given batch sizes.

    Parameters
    ----------
    sequences: torch.Tensor [N, ...]
        The data tensor of the packed sequences (number of total elements N).
    batch_sizes: torch.Tensor [B]
        The batch sizes (maximum sequence length B).

    Returns
    -------
    torch.Tensor [N - S, ...]
        The data of the packed sequences where each sequence's first element has been dropped
        (number of sequences S).
    """
    num_sequences = batch_sizes[0].item()
    return sequences[num_sequences:]


def heading(text, level=1):
    """Render the supplied text as a heading.

	Parameters
	----------
	text : str
		The text to render as a heading
	level : int
		The heading level from 1 upward.
	"""
    if level == 1:
        return '{}\n{}\n'.format(text, '=' * len(text))
    elif level == 2:
        return '{}\n{}\n'.format(text, '-' * len(text))
    else:
        return '{} {}\n'.format('#' * level, text)


def _helper_reraises_exception(ex):
    """Pickle-able helper function for use by _guarded_task_generation."""
    raise ex


@staticmethod
def generateSimpleHtmlTableMessage(informationOrderedDictionary):
    """
        Generates a table based on a dictionary provided.

        :param informationOrderedDictionary: (OrderedDict) dict of information to show in table
        :return: (String) html table representation of dictionary provided.
        """
    result = '
'
    for infoItemKey, infoItemValue in informationOrderedDictionary.items():
        if infoItemValue is not None and infoItemValue != '':
            infoItemValueTdAttributes = ''
            if str(infoItemValue).isdigit():
                infoItemValueTdAttributes = "align='right'"
            row = '
%s 	%s
' % (infoItemKey,
                infoItemValueTdAttributes, infoItemValue)
            result += row
    result += '
'
    return result


def to_ascii_hex(value: int, digits: int) ->str:
    """Converts an int value to ASCII hex, as used by LifeSOS.
       Unlike regular hex, it uses the first 6 characters that follow
       numerics on the ASCII table instead of A - F."""
    if digits < 1:
        return ''
    text = ''
    for _ in range(0, digits):
        text = chr(ord('0') + value % 16) + text
        value //= 16
    return text


def shutdown():
    """
    Perform shutdown of non-active hosted channels. Wait
    for active hosted channels to become non-active.
    """
    return


@classmethod
def _update_es_facets(cls, search_obj, filterable_attributes=None,
    facet_filter=None):
    """
        This method takes the input `~pyes.query.Search` object, and then
        adds appropriate terms to the `facet` attribute of this object. By
        default, term facets are generated over filterable attributes.
        """
    if not filterable_attributes:
        return
    for attribute in filterable_attributes:
        search_obj.facet.add_term_facet(attribute.name, facet_filter=
            facet_filter, all_terms=attribute.multiselect, size=attribute.
            display_size, order=attribute.display_order)


def _scrub_empty_str_values(dct, keys_to_scrub):
    """Remove any keys found in sequence keys_to_scrub from the dict
    if they have the value ''.
    """
    for key in keys_to_scrub:
        if key in dct and dct[key] == '':
            del dct[key]


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


def _dispose(mlist, msg, msgdata):
    """Dispose of a single message destined for a mailing list.

        Called for each message that the runner is responsible for, this is
        the primary overridable method for processing each message.
        Subclasses, must provide implementation for this method.

        :param mlist: The mailing list this message is destined for.
        :type mlist: `IMailingList`
        :param msg: The message being processed.
        :type msg: `email.message.Message`
        :param msgdata: The message metadata.
        :type msgdata: dict
        :return: True if the message should continue to be queued, False if
            the message should be deleted automatically.
        :rtype: bool
        """


def getplaylist():
    """
    @api {post} /music/playlist/getplaylist 获取用户歌单
    @apiVersion 1.0.0
    @apiGroup Playlist
    @apiDescription 获取用户歌单

    @apiParam (Headers) {string} token 令牌
    @apiParam (Headers) {String} device_token 设备令牌
    @apiParam (Headers) {String} content_type 内容类型
    @apiParam (Headers) {String} timestamp 时间戳

    @apiSuccess (Success) {Object} playlistid 播放列表编号
    @apiSuccess (Success) {Object} playlistname 播放列表名称
    @apiSuccess (Success) {Object} imageS 小尺寸图片
    @apiSuccess (Success) {Object} imageM 中等尺寸图片
    @apiSuccess (Success) {Object} imageL 大尺寸图片

    @apiSuccessExample {json} Success-Response:
    {
        "data": [
            {
                "playlistid": 1,
                "playlistname": "我的列表",
                "imageS": null,
                "imageM": null,
                "imageL": null
            }
        ]
    }

    """


def get_preview_fps(project):
    """
    Return fps set at project level or default fps if the dimensions are not
    set.
    """
    fps = '24.00'
    if project['fps'] is not None:
        fps = '%.2f' % float(project['fps'].replace(',', '.'))
    return fps


def scale(scale: list):
    """Scale the current stack matrix.

    :param scale: Scale the current stack matrix.
    :type scale: list
    """
    pass


def configure(**kwargs):
    """
    Valid keyword arguments with defaults (other ignored):
      assumeSortedIndices = False

    Umfpack requires a CSR/CSC matrix to have sorted column/row indices. If
    sure that the matrix fulfills this, pass assumeSortedIndices =
    True to gain some speed.
    """
    if 'assumeSortedIndices' in kwargs:
        globals()['assumeSortedIndices'] = kwargs['assumeSortedIndices']


def _check_shape(s1, s2):
    """check s1 == s2 if both are not None"""
    if s1 and s2 and s1 != s2:
        raise ValueError('Shape mismatch detected. ' + str(s1) + ' v.s. ' +
            str(s2))


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


@classmethod
def __format_synonyms(cls, synonyms):
    """
        Returns a str that will be written in the output files for all
        the synonyms `synonyms`.
        """
    result = ''
    for syn_name in synonyms:
        if len(synonyms[syn_name]) > 1:
            result += '## synonym:' + syn_name + '\n'
            for syn in synonyms[syn_name]:
                if syn != syn_name:
                    result += '- ' + syn + '\n'
            result += '\n'
    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 '+'


def pack(msg):
    """
    Returns the JSON representation of a Call, CallError or CallResult.

    It just calls the 'to_json()' method of the message. But it is here mainly
    to complement the 'unpack' function of this module.
    """
    return msg.to_json()


def distance(pt1, pt2):
    """
    Simple 2d euclidean distances between two points.
    args:
        pt1: The first point.
        pt2: The second point.
    """
    return (pt1[0] - pt2[0]) ** 2 + (pt1[1] - pt2[1]) ** 2


@classmethod
def match_header(cls, header):
    """
        This is an abstract type that implements the shared functionality of
        the ASCII and Binary Table HDU types, which should be used instead of
        this.
        """
    raise NotImplementedError


def extract_csv_links(text):
    """Get a list of csv links from the download link response text"""
    links = text.replace('\r', '').split('\n')
    links.remove('')
    return links


def pgettext_data(msgid: str, msgctxt: str):
    """Try to translate the given msgid (with optional msgctxt), if new data name’s translation is enabled.

    :param msgid: The string to translate.
    :type msgid: str
    :param msgctxt: The translation context (defaults to BLT_I18NCONTEXT_DEFAULT).
    :type msgctxt: str
    :return:  The translated string (or msgid if no translation was found).
    """
    pass


def brightness_from_percentage(percent):
    """Convert percentage to absolute value 0..255."""
    return percent * 255.0 / 100.0


@staticmethod
def iterator(fn):
    """Tag the method as the collection remover.

        The iterator method is called with no arguments.  It is expected to
        return an iterator over all collection members::

            @collection.iterator
            def __iter__(self): ...

        """
    fn._sa_instrument_role = 'iterator'
    return fn


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

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

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


def preparse_address(addr_spec):
    """
    Preparses email addresses. Used to handle odd behavior by ESPs.
    """
    parts = addr_spec.split('@')
    if len(parts) < 2:
        return None
    return parts


@classmethod
def create(cls, node=None, to_type=None, to_id=None, amount=None, currency=
    None, ip=None, idempotency_key=None, **kwargs):
    """Create a trans record in API and corresponding Transaction instance.

        Args:
            node (BaseNode): the node from which to send funds
            to_type (str): type of the 'to' node (e.g. 'ACH-US')
            to_id (id): id of the 'to' node
            amount (float): amount of currency
            currency (str): type of currency (e.g. 'USD')
            ip (str): ip of the sender
            idempotency_key (str): avoid accidentally performing the same operation twice
            process_in (int): delay in days until processing (default 1)
            note (str): a note to synapse
            supp_id (str): a supplementary id
            fees (list): fees associated with the transaction
            fee_amount (float): an additional fee to include (deprecated)
            fee_note (str): a note to go with the fee (deprecated)
            fee_to_id (str): the node id from which to take the fee (deprecated)

        Returns:
            Transaction: a new Transaction instance
        """
    payload = cls.payload_for_create(to_type, to_id, amount, currency, ip,
        **kwargs)
    response = node.user.client.trans.create(node.user.id, node.id, payload,
        idempotency_key)
    return cls.from_response(node, response)


def help_text():
    """Provide instruction about useage"""
    print(
        """Please follow the instruction
* To start command `gittivity-start <your github_handle>`
* To stop command `gittivity-stop`
* To get hint command `gittivity` for instruction
"""
        )


def contains_digit(text: str) ->bool:
    """If text contains a digit, return True."""
    for character in text:
        if character.isnumeric():
            return True
    return False


def truncate_path(path: str, degree: int) ->str:
    """
    degree  |   result
    ==================
    0       |   full path
    1       |   parent directory
    2       |   parent's parent directory
    ...
    """
    if degree < 0:
        raise IndexError('degree cannot be a negative integer')
    if degree == 0:
        return path
    return '/'.join(path.split('/')[0:-degree])


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

        :param DomainInvitesRequestToJoinTeamDetails val:
        :rtype: EventDetails
        """
    return cls('domain_invites_request_to_join_team_details', val)


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

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


def delete_event_subscription(SubscriptionName=None):
    """
    Deletes an Amazon Redshift event notification subscription.
    See also: AWS API Documentation

    :example: response = client.delete_event_subscription(
        SubscriptionName='string'
    )

    :type SubscriptionName: string
    :param SubscriptionName: [REQUIRED]
            The name of the Amazon Redshift event notification subscription to be deleted.

    """
    pass


def pushInput(data, out):
    """Push block of inputted data into processor.

        Processor writes data to pass along on input stream to
        out, using .write().
        """


def get_longest_line_length(text):
    """Get the length longest line in a paragraph"""
    lines = text.split('\n')
    length = 0
    for i in range(len(lines)):
        if len(lines[i]) > length:
            length = len(lines[i])
    return length


def write_string_to_file(path, string, append=False):
    """
    Write string to file.
    :param path: File where we want to put the string.
    :param string: New content.
    :param append: If True, append to file, else overwrite.
    """
    with open(path, 'a' if append else 'w') as f:
        f.write(string)


def gmctime():
    """
    Returns the current time as a string in RFC3339 format.
    """
    import time
    return time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime())


def dedup(l, suffix='__', case_sensitive=True):
    """De-duplicates a list of string by suffixing a counter

    Always returns the same number of entries as provided, and always returns
    unique values. Case sensitive comparison by default.

    >>> print(','.join(dedup(['foo', 'bar', 'bar', 'bar', 'Bar'])))
    foo,bar,bar__1,bar__2,Bar
    >>> print(
        ','.join(dedup(['foo', 'bar', 'bar', 'bar', 'Bar'], case_sensitive=False))
    )
    foo,bar,bar__1,bar__2,Bar__3
    """
    new_l = []
    seen = {}
    for s in l:
        s_fixed_case = s if case_sensitive else s.lower()
        if s_fixed_case in seen:
            seen[s_fixed_case] += 1
            s += suffix + str(seen[s_fixed_case])
        else:
            seen[s_fixed_case] = 0
        new_l.append(s)
    return new_l


def db2lin(a, amplitude=False):
    """ Mini routine to convert dB to linear"""
    if amplitude:
        return 10 ** (a / 20)
    else:
        return 10 ** (a / 10)


def vertex_add(location: float=(0.0, 0.0, 0.0)):
    """Add a new control point (linked to only selected end-curve one, if any)

    :param location: Location, Location to add new vertex at
    :type location: float
    """
    pass


def hours_time_string(hours):
    """ convert a number of hours (float) into a string with format '%H:%M' """
    minutes = int(round(hours * 60))
    return '%02d:%02d' % divmod(minutes, 60)


def node_has_a_filter(node, filter_func_name):
    """ returns True if the node has the given filter_func_name
        , e.g. 'safe',  otherwise returns False.
    """
    if not hasattr(node, 'filter_expression'):
        return False
    for _filter in node.filter_expression.filters:
        if _filter and _filter[0].__name__ == filter_func_name:
            return True
    return False


def addAfterAbortHook(hook, args=(), kws=None):
    """Register a hook to call after a transaction abort.

        The specified hook function will be called after the
        transaction abort.

        *args* and *kws* are interpreted as for `addBeforeCommitHook`.
        As with `addBeforeCommitHook`, multiple hooks can be
        registered, savepoint creation doesn't call any hooks, and
        calling a hook consumes its registration.

        As with `addBeforeAbortHook`, these hooks are called only for
        a top-level abort. See that method for more.
        """


def render_with_pymol_server(parsed_file, output_path=None, width=1200, **
    kwargs):
    """Render ESIgenReport with PyMol (server-client model)"""
    if output_path is None:
        output_path = parsed_file.path + '.png'
    from ._pymol_server import pymol_client
    client = pymol_client()
    client.do('reinitialize')
    client.loadPDB(parsed_file.data.pdb_block, parsed_file.name)
    client.do('bg_color white')
    client.do('preset.ball_and_stick()')
    client.do('set sphere_scale, 0.2, symbol H')
    client.do('set float_labels, on')
    client.do('set label_position, 0 0 5')
    client.do('alter not symbol C+H+O+N+P+S, vdw=3')
    client.do('util.cbag()')
    client.do('color grey, symbol C')
    client.do('label not symbol C+H+O+N+P+S, name')
    client.do('png {}, width={}, ray=1, quiet=1'.format(output_path, width))
    client.do('refresh')
    client.do('cmd.sync()')
    return output_path


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


def tabs(num):
    """ Compute a blank tab """
    return '  ' * num


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

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

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

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

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

    """
    pass


def 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


@classmethod
def to_dict(cls, obj, key='name'):
    """
        convert the object to dict

        :param obj:
        :return:
        """
    result = dict()
    for u in obj:
        if u is not None:
            values = {}
            for attribute in list(u.__dict__.keys()):
                if not attribute.startswith('_sa'):
                    values[attribute] = u.__dict__[attribute]
            result[values[key]] = values
    return result


def describe_virtual_interfaces(connectionId=None, virtualInterfaceId=None):
    """
    Displays all virtual interfaces for an AWS account. Virtual interfaces deleted fewer than 15 minutes before you make the request are also returned. If you specify a connection ID, only the virtual interfaces associated with the connection are returned. If you specify a virtual interface ID, then only a single virtual interface is returned.
    A virtual interface (VLAN) transmits the traffic between the AWS Direct Connect location and the customer.
    See also: AWS API Documentation

    :example: response = client.describe_virtual_interfaces(
        connectionId='string',
        virtualInterfaceId='string'
    )

    :type connectionId: string
    :param connectionId: The ID of the connection. This field is also used as the ID type for operations that use multiple connection types (LAG, interconnect, and/or connection).
            Example: dxcon-fg5678gh
            Default: None

    :type virtualInterfaceId: string
    :param virtualInterfaceId: The ID of the virtual interface.
            Example: dxvif-123dfg56
            Default: None

    :rtype: dict
    :return: {
        'virtualInterfaces': [
            {
                'ownerAccount': 'string',
                'virtualInterfaceId': 'string',
                'location': 'string',
                'connectionId': 'string',
                'virtualInterfaceType': 'string',
                'virtualInterfaceName': 'string',
                'vlan': 123,
                'asn': 123,
                'authKey': 'string',
                'amazonAddress': 'string',
                'customerAddress': 'string',
                'addressFamily': 'ipv4'|'ipv6',
                'virtualInterfaceState': 'confirming'|'verifying'|'pending'|'available'|'down'|'deleting'|'deleted'|'rejected',
                'customerRouterConfig': 'string',
                'virtualGatewayId': 'string',
                'routeFilterPrefixes': [
                    {
                        'cidr': 'string'
                    },
                ],
                'bgpPeers': [
                    {
                        'asn': 123,
                        'authKey': 'string',
                        'addressFamily': 'ipv4'|'ipv6',
                        'amazonAddress': 'string',
                        'customerAddress': 'string',
                        'bgpPeerState': 'verifying'|'pending'|'available'|'deleting'|'deleted',
                        'bgpStatus': 'up'|'down'
                    },
                ]
            },
        ]
    }

    :returns:
    ipv4 : IPv4 address family
    ipv6 : IPv6 address family

    """
    pass


def _np_conv_ok(volume, kernel, mode):
    """
    See if numpy supports convolution of `volume` and `kernel` (i.e. both are
    1D ndarrays and of the appropriate shape).  Numpy's 'same' mode uses the
    size of the larger input, while Scipy's uses the size of the first input.
    """
    np_conv_ok = volume.ndim == kernel.ndim == 1
    return np_conv_ok and (volume.size >= kernel.size or mode != 'same')


def get_all_perms(obj):
    """Return a list of all permissions on ``obj``."""
    return list(zip(*obj._meta.permissions))[0]


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 psi_Ca_HSO4_SO4_HMW84(T, P):
    """c-a-a': calcium bisulfate sulfate [HMW84]."""
    psi = 0.0
    valid = T == 298.15
    return psi, valid


@classmethod
def get(cls, project_id, job_id):
    """
        Fetches one job.

        Parameters
        ----------
        project_id : str
            The identifier of the project in which the job resides
        job_id : str
            The job id

        Returns
        -------
        job : Job
            The job

        Raises
        ------
        AsyncFailureError
            Querying this resource gave a status code other than 200 or 303
        """
    url = cls._job_path(project_id, job_id)
    data, completed_url = cls._data_and_completed_url_for_job(url)
    return cls(data, completed_resource_url=completed_url)


def substitute_args(args, student_path, seed):
    """
    Updates the given arguments by replacing $template values with the given ones.

    Args:
        arg (List[str]):
        student_path (str):
        seed (Any):

    Returns:

    """
    for arg in args.split(','):
        if arg == '$_STUDENT_MAIN':
            yield student_path
        elif arg == '$_STUDENT_NAME':
            yield seed
        yield arg


def legendre_symbol(a, p):
    """ Compute the Legendre symbol a|p using
    Euler's criterion. p is a prime, a is
    relatively prime to p (if p divides
    a, then a|p = 0)

    Returns 1 if a has a square root modulo
    p, -1 otherwise.
    """
    ls = pow(a, (p - 1) // 2, p)
    return -1 if ls == p - 1 else ls


def coerce_to_int(val, default=3735928559):
    """Attempts to cast given value to an integer, return the original value if failed or the default if one provided."""
    try:
        return int(val)
    except (TypeError, ValueError):
        if default != 3735928559:
            return default
        return val


def zrodlo_post_save(instance, *args, **kw):
    """Źródło zostało zapisane (post_save)
    """
    changed = getattr(instance, '_BPP_CHANGED_FIELDS', [])
    if not changed:
        changed = kw.get('update_fields') or []
    if 'skrot' in changed:
        from bpp.tasks import zaktualizuj_zrodlo
        zaktualizuj_zrodlo.delay(instance.pk)


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


def disable_radius(DirectoryId=None):
    """
    Disables multi-factor authentication (MFA) with the Remote Authentication Dial In User Service (RADIUS) server for an AD Connector directory.
    See also: AWS API Documentation

    :example: response = client.disable_radius(
        DirectoryId='string'
    )

    :type DirectoryId: string
    :param DirectoryId: [REQUIRED]
            The identifier of the directory for which to disable MFA.

    :rtype: dict
    :return: {}

    """
    pass


def HTML_Overall_Params_Table(Input_Dict, Input_Params, file, header=False):
    """
    Add table to html file.

    :param Input_Dict: input values dictionary
    :type Input_Dict : dict
    :param Input_Params: input parameters dictionary
    :type Input_Params : dict
    :param file: html file object
    :type file : file object
    :return: None
    """
    if header:
        file.write('
Overall Parameters
\n')
    file.write(
        '
\n'
        )
    file.write(
        '
\n'
        )
    file.write(
        '\n'
         + 'Parameter\n	')
    file.write(
        '\n'
         + """Description
	""")
    file.write(
        '\n'
         + """Value

""")
    Input_Params_Keys = sorted(Input_Params.keys())
    for key in Input_Params_Keys:
        file.write(
            """

"""
            )
        file.write(
            '\n'
             + key + '\n	\n')
        file.write(
            '\n'
             + Input_Params[key] + '\n	\n')
        file.write(
            '\n'
             + str(Input_Dict[key]) + '\n	\n')
    file.write('
\n')
    if header:
        file.write('
Graphs
\n')


def resolve_stack_name(source_stack_name, destination_stack_path):
    """
    Returns a stack's full name.

    A dependancy stack's name can be provided as either a full stack name, or
    as the file base name of a stack from the same environment.
    resolve_stack_name calculates the dependency's stack's full name from this.

    :param source_stack_name: The name of the stack with the parameter to be     resolved.
    :type source_stack_name: str
    :param destination_stack_path: The full or short name of the depenency     stack.
    :type destination_stack_path: str
    :returns: The stack's full name.
    :rtype: str
    """
    if '/' in destination_stack_path:
        return destination_stack_path
    else:
        source_stack_base_name = source_stack_name.rsplit('/', 1)[0]
        return '/'.join([source_stack_base_name, destination_stack_path])


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


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


def error(msg):
    """log error message"""


@staticmethod
def readfile(file_path):
    """
        return the content of the file <file_path>
        :param file_path: File path to read
        :return: Str content of the file
        """
    file_to_read = open(file_path, 'r')
    return file_to_read.read()


def _tensor_max(*args):
    """Elementwise maximum of a sequence of tensors"""
    maximum, *rest = args
    for arg in rest:
        maximum = maximum.max(arg)
    return maximum


def ancestral_sequence_inference(tree=None, aln=None, ref=None, infer_gtr=
    True, marginal=False, fill_overhangs=True, infer_tips=False):
    """infer ancestral sequences using TreeTime

    Parameters
    ----------
    tree : Bio.Phylo tree or str
        tree or filename of tree
    aln : Bio.Align.MultipleSeqAlignment or str
        alignment or filename of alignment
    infer_gtr : bool, optional
        Description
    marginal : bool, optional
        Description
    fill_overhangs : bool
       In some cases, the missing data on both ends of the alignment is
       filled with the gap character ('-'). If set to True, these end-gaps are
       converted to "ambiguous" characters ('N' for nucleotides, 'X' for
       aminoacids). Otherwise, the alignment is treated as-is
    infer_tips : bool
        Since v0.7, TreeTime does not reconstruct tip states by default.
        This is only relevant when tip-state are not exactly specified, e.g. via
        characters that signify ambiguous states. To replace those with the
        most-likely state, set infer_tips=True

    Returns
    -------
    TreeAnc
        treetime.TreeAnc instance
    """
    from treetime import TreeAnc
    tt = TreeAnc(tree=tree, aln=aln, ref=ref, gtr='JC69', fill_overhangs=
        fill_overhangs, verbose=1)
    bool_marginal = marginal == 'marginal'
    tt.infer_ancestral_sequences(infer_gtr=infer_gtr, marginal=
        bool_marginal, reconstruct_tip_states=infer_tips)
    print(
        """
Inferred ancestral sequence states using TreeTime:
	Sagulenko et al. TreeTime: Maximum-likelihood phylodynamic analysis
	Virus Evolution, vol 4, https://academic.oup.com/ve/article/4/1/vex042/4794731
"""
        )
    return tt


def str_to_bytes(input_str):
    """Convert string to bytes.
  """
    return input_str.encode()


def iterprod(l):
    """
    Product of the elements of any iterable.  Product of empty iterable == 1.
    Input: l -- iterable
    Output: A number
    Examples:
    >>> listprod(range(1, 8))
    5040
    """
    z = 1
    for x in l:
        z *= x
    return z


def affine_bkg(x, lin_bkg=0, const_bkg=0):
    """
    An affine/linear background.
    :param x:
    :param lin_bkg:
    :param const_bkg:
    :return:
    """
    return lin_bkg * x + const_bkg


def is_installed(module):
    """Tests to see if ``module`` is available on the sys.path

    >>> is_installed('sys')
    True
    >>> is_installed('hopefullythisisnotarealmodule')
    False

    """
    try:
        __import__(module)
        return True
    except ImportError:
        return False


def isfilecached(repo, name):
    """check if a repo has already cached "name" filecache-ed property

    This returns (cachedobj-or-None, iscached) tuple.
    """
    cacheentry = repo.unfiltered()._filecache.get(name, None)
    if not cacheentry:
        return None, False
    return cacheentry.obj, True


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

    The ceil of the scalar x is the smallest integer i, such that i >= x.

    Example::

       ceil([-2.1, -1.9, 1.5, 1.9, 2.1]) = [-2., -1.,  2.,  2.,  3.]

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

       - ceil(default) = default
       - ceil(row_sparse) = row_sparse
       - ceil(csr) = csr

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

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

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

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


def tokenize_conf_stream(conf_handle):
    """
    convert the key=val pairs in a LSF config stream to tuples of tokens
    """
    for line in conf_handle:
        if line.startswith('#'):
            continue
        tokens = line.split('=')
        if len(tokens) != 2:
            continue
        yield tokens[0].strip(), tokens[1].strip()


def add_flag(argparser, flag_name: str, **kwargs):
    """Add a CLI argument for the flag.

    The flag defaults to False, and when present on the CLI stores True.
    """
    argparser.add_argument('-%s' % flag_name[0], '--%s' % flag_name,
        default=False, action='store_true', **kwargs)


@staticmethod
def bitSizeOf():
    """
        Returns length of Zserio bool type stored in the bit stream in bits.

        :returns: Length of Zserio bool type in bits.
        """
    return 1


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 get_symmetric_vertex(vertex_index, sym_table_list):
    """
    Returns symmetric vertex or -1 if not symmetric vertex found
    :param vertex_index: int
    """
    for i in range(len(sym_table_list)):
        if int(vertex_index) == int(sym_table_list[i]):
            if i % 2 == 0:
                sym_vtx = sym_table_list[i + 1]
            else:
                sym_vtx = sym_table_list[i - 1]
            break
    return sym_vtx


def isCanonical():
    """
        boolean, is this the original, canonical translation of the content.
        """


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

        :param UserCustomQuotaResult val:
        :rtype: CustomQuotaResult
        """
    return cls('success', val)


@classmethod
def axesNames(cls):
    """ The names of the axes that this inspector visualizes.
            See the parent class documentation for a more detailed explanation.
        """
    return tuple(['Y', 'X'])


def upcase(string):
    """Return an uppercase version of the string.

    Used for the type argument in argparse/
    """
    return string.upper()


def isnumeric(text):
    """
    Returns a True if the text is purely numeric and False otherwise.
    """
    try:
        float(text)
    except ValueError:
        return False
    else:
        return True


def _make_dropdown_lists(options):
    """This takes a list of label/value dicts (with arbitrary type values)
    and returns list and dict. Needed since dcc.Dropdown can only take str
    values. identity is fed to dcc.Dropdown() and mapper is used for getting
    the actual values at the callback."""
    identity = list()
    mapper = dict()
    for option in options:
        di = {'label': option['label'], 'value': option['label']}
        if 'disabled' in option and option['disabled']:
            di['disabled'] = True
        identity.append(di)
        mapper[option['label']] = option['value']
    return identity, mapper


@staticmethod
def _get_main(job):
    """Add main program to command. Override this for programs
        where main is given as a parameter, e.g. for GATK"""
    return job.main()


@staticmethod
def in_(a, b):
    """ Literally implement membership test. Make it a static method so we
        can do identity checks. Do not use operator.contains because it needs
        operands swapped. """
    return a in b


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 describe_hosted_connections(connectionId=None):
    """
    Returns a list of hosted connections that have been provisioned on the given interconnect or link aggregation group (LAG).
    See also: AWS API Documentation

    :example: response = client.describe_hosted_connections(
        connectionId='string'
    )

    :type connectionId: string
    :param connectionId: [REQUIRED]
            The ID of the interconnect or LAG on which the hosted connections are provisioned.
            Example: dxcon-abc123 or dxlag-abc123
            Default: None

    :rtype: dict
    :return: {
        'connections': [
            {
                'ownerAccount': 'string',
                'connectionId': 'string',
                'connectionName': 'string',
                'connectionState': 'ordering'|'requested'|'pending'|'available'|'down'|'deleting'|'deleted'|'rejected',
                'region': 'string',
                'location': 'string',
                'bandwidth': 'string',
                'vlan': 123,
                'partnerName': 'string',
                'loaIssueTime': datetime(2015, 1, 1),
                'lagId': 'string',
                'awsDevice': 'string'
            },
        ]
    }

    """
    pass


def parse_headers(str):
    """Parses a HTTP-style headers"""
    headers = {}
    for line in str.split('\n'):
        if len(line) == 0:
            continue
        key, value = line.split(': ', 1)
        headers[key] = value
    return headers


def _needs_to_implement(that, func_name):
    """Helper to raise NotImplementedError in interface stubs."""
    if hasattr(that, '_coverage_plugin_name'):
        thing = 'Plugin'
        name = that._coverage_plugin_name
    else:
        thing = 'Class'
        klass = that.__class__
        name = '{klass.__module__}.{klass.__name__}'.format(klass=klass)
    raise NotImplementedError(
        '{thing} {name!r} needs to implement {func_name}()'.format(thing=
        thing, name=name, func_name=func_name))


def reverse(xs):
    """Returns a reversed sequence"""
    return type(xs)(reversed(xs))


def sqdist3(x1, y1, z1, x2, y2, z2, ind, rotmat):
    """Squared Anisotropic Distance Calculation Given Matrix Indicator - 3D

    This routine calculates the anisotropic distance between two points
    given the coordinates of each point and a definition of the
    anisotropy.

    Converted from original fortran GSLIB (Deutsch and Journel, 1998) to Python by Wendi Liu, University of Texas at Austin

    INPUT VARIABLES:

    x1,y1,z1         Coordinates of first point
    x2,y2,z2         Coordinates of second point
    ind              The rotation matrix to use
    rotmat           The rotation matrices"""
    dx = x1 - x2
    dy = y1 - y2
    dz = z1 - z2
    sqdist = 0.0
    for i in range(3):
        cont = rotmat[ind, i, 0] * dx + rotmat[ind, i, 1] * dy + rotmat[ind,
            i, 2] * dz
        sqdist += cont ** 2
    return sqdist


def _is_plotly_obj(obj):
    """True if input if from a type that lives in plotly.plotly_objs."""
    the_type = type(obj)
    return the_type.__module__.startswith('plotly.graph_objs')


@staticmethod
def decompose(minutes_to_add):
    """Break down minutes-to-add into hours, minutes and seconds."""
    h = int(minutes_to_add / 60)
    m = int(minutes_to_add - 60 * h)
    s = round(60 * (minutes_to_add % 1))
    return h, m, s


def get_cl(a):
    """Return GPUArray from GPU memory as NumPy array.

    Parameters
    ----------
    a : gpuarray
        Data on the GPU memory to retrieve.

    Returns
    -------
    array
        The GPUArray returned to RAM as a NumPy array.

    Examples
    --------
    >>> a = give_cl([1, 2, 3])
    >>> b = get_cl(a)
    [ 1.,  2.,  3.]

    >>> type(b)
    <class 'numpy.ndarray'>
    """
    return a.get()


def select_input(context):
    """
    Dependencies for select2_input gizmo.
    """
    return ('tethys_gizmos/vendor/select2_3.5.1/select2.css',
        'tethys_gizmos/vendor/select2_3.5.1/select2.js')


def make_naive(value, timezone):
    """
    Makes an aware datetime.datetime naive in a given time zone.
    """
    value = value.astimezone(timezone)
    if hasattr(timezone, 'normalize'):
        value = timezone.normalize(value)
    return value.replace(tzinfo=None)


@classmethod
def cass_parameterized_type(cls, full=False):
    """
        Return a Cassandra type specifier for this type. If this type has
        parameters, they are included in the standard () notation.
        """
    return cls.cass_parameterized_type_with(cls.subtypes, full=full)


def transpose_axes(image, axes, asaxes=None):
    """Return image with its axes permuted to match specified axes.

    A view is returned if possible.

    >>> transpose_axes(numpy.zeros((2, 3, 4, 5)), 'TYXC', asaxes='CTZYX').shape
    (5, 2, 1, 3, 4)

    """
    for ax in axes:
        if ax not in asaxes:
            raise ValueError(f'unknown axis {ax}')
    if asaxes is None:
        asaxes = 'CTZYX'
    shape = image.shape
    for ax in reversed(asaxes):
        if ax not in axes:
            axes = ax + axes
            shape = (1,) + shape
    image = image.reshape(shape)
    image = image.transpose([axes.index(ax) for ax in asaxes])
    return image


@staticmethod
def _calculate_checksum(data, number_of_bytes):
    """5.7 CRC Checksum using the polynomial given in the datasheet
		Credits: https://github.com/jaques/sht21_python/blob/master/sht21.py
		"""
    POLYNOMIAL = 305
    crc = 0
    for byteCtr in range(number_of_bytes):
        crc ^= data[byteCtr]
        for bit in range(8, 0, -1):
            if crc & 128:
                crc = crc << 1 ^ POLYNOMIAL
            else:
                crc = crc << 1
    return crc


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 identity(x):
    """Return the argument unchanged.
       This function is often called `identity` in programming language
       and type theory (the type is t -> t, which turns out to be a
       difficult type for most classical static type systems).
    """
    return x


@staticmethod
def parse_type(data):
    """
        Convert a OMS `data` JSON file into an Output type.
        """
    ty = data['type']
    if ty == 'list':
        from storyhub.sdk.service.output.OutputList import OutputList
        return OutputList.from_dict(data)
    if ty == 'map':
        from storyhub.sdk.service.output.OutputMap import OutputMap
        return OutputMap.from_dict(data)
    if ty == 'object':
        from storyhub.sdk.service.output.OutputObject import OutputObject
        return OutputObject.from_dict(data)
    if ty == 'int' or ty == 'number':
        from storyhub.sdk.service.output.OutputInt import OutputInt
        return OutputInt.from_dict(data)
    if ty == 'float':
        from storyhub.sdk.service.output.OutputFloat import OutputFloat
        return OutputFloat.from_dict(data)
    if ty == 'boolean':
        from storyhub.sdk.service.output.OutputBoolean import OutputBoolean
        return OutputBoolean.from_dict(data)
    if ty == 'enum':
        from storyhub.sdk.service.output.OutputEnum import OutputEnum
        return OutputEnum.from_dict(data)
    if ty == 'regex':
        from storyhub.sdk.service.output.OutputRegex import OutputRegex
        return OutputRegex.from_dict(data)
    if ty == 'none':
        from storyhub.sdk.service.output.OutputNone import OutputNone
        return OutputNone.from_dict(data)
    if ty == 'any':
        from storyhub.sdk.service.output.OutputAny import OutputAny
        return OutputAny.from_dict(data)
    from storyhub.sdk.service.output.OutputString import OutputString
    assert ty == 'string', f'{ty} with {data} is unknown'
    return OutputString.from_dict(data)


@classmethod
def date_data_from_form(cls, form):
    """Translate a :class:`~app.forms.CreateEventForm` or a subclass into a
        dictionary of date data.

        :param form: The form to translate.
        :type form: :class:`~app.forms.CreateEventForm` or a subclasss

        :returns: Date data.
        :rtype: dict
        """
    if not form:
        return {}
    return {'start_date': form.start_date.data, 'end_date': form.end_date.data}


def _image_member_format(member_ref):
    """Format a member ref for consumption outside of this module."""
    return {'id': member_ref['id'], 'image_id': member_ref['image_id'],
        'member': member_ref['member'], 'can_share': member_ref['can_share'
        ], 'status': member_ref['status'], 'created_at': member_ref[
        'created_at'], 'updated_at': member_ref['updated_at'], 'deleted':
        member_ref['deleted']}


def _analyse_gdal_output(output):
    """analyse the output from gpt to find if it executes successfully."""
    if b'error' in output.lower():
        return False
    elif b'100 - done' in output.lower():
        return True
    else:
        return False


def color_to_RGB(color):
    """Convert a 24-bit color value to 8-bit red, green, blue components.
    Will return a 3-tuple with the color component values.
    """
    return color >> 16 & 255, color >> 8 & 255, color & 255


def is_x11_compositing_enabled():
    """Is X11 compositing manager running.
    """
    try:
        from AnyQt.QtX11Extras import QX11Info
    except ImportError:
        return False
    if hasattr(QX11Info, 'isCompositingManagerRunning'):
        return QX11Info.isCompositingManagerRunning()
    else:
        return False


@classmethod
def parse_options(cls, options):
    """Extracts subdomain and endpoint values from the options dict and returns
           them along with a new dict without those values.
        """
    options = options.copy()
    subdomain = options.pop('subdomain', None)
    endpoint = options.pop('endpoint', None)
    return subdomain, endpoint, options


def build_url(hub_base_url: str, org: str, workspace: str) ->str:
    """
    Build the base URL of the Chaos Hub workspace where the experiment and
    the journal will be stored and be made visible.
    """
    return '/'.join([hub_base_url, 'api', org, workspace])


def decrypt_seiga_drm(enc_bytes, key):
    """Decrypt the light DRM applied to certain Seiga images."""
    n = []
    a = 8
    for i in range(a):
        start = 2 * i
        value = int(key[start:start + 2], 16)
        n.append(value)
    dec_bytes = bytearray(enc_bytes)
    for i in range(len(enc_bytes)):
        dec_bytes[i] = dec_bytes[i] ^ n[i % a]
    return dec_bytes


def hydroxyl(universe, seg, i):
    """2-hydroxyl dihedral. Useful only for RNA calculations.

     .. Note:: This dihedral calculation will only work if using atom
               names as documented by charmm force field parameters,
               namely "C1', C2', O2', H2'".

    Parameters
    ----------
    universe : Universe
         :class:`~MDAnalysis.core.universe.Universe` containing the trajectory
    seg : str
        segment id for base
    i : int
        resid of the first base

    Returns
    -------
    hydroxyl_angle : float
        torsion angle in degrees

    .. versionadded:: 0.7.6

    """
    h = universe.select_atoms("atom {0!s} {1!s} C1'".format(seg, i),
        "atom {0!s} {1!s} C2'".format(seg, i), "atom {0!s} {1!s} O2'".
        format(seg, i), "atom {0!s} {1!s} H2'".format(seg, i))
    try:
        hydr = h.dihedral.value() % 360
    except ValueError:
        raise ValueError(
            "Resid {0} does not contain atoms C1', C2', O2', H2' but atoms {1}"
            .format(i, str(list(h.atoms))))
    return hydr


def list_offering_promotions(nextToken=None):
    """
    Returns a list of offering promotions. Each offering promotion record contains the ID and description of the promotion. The API returns a NotEligible error if the caller is not permitted to invoke the operation. Contact aws-devicefarm-support@amazon.com if you believe that you should be able to invoke this operation.
    See also: AWS API Documentation

    :example: response = client.list_offering_promotions(
        nextToken='string'
    )

    :type nextToken: string
    :param nextToken: An identifier that was returned from the previous call to this operation, which can be used to return the next set of items in the list.

    :rtype: dict
    :return: {
        'offeringPromotions': [
            {
                'id': 'string',
                'description': 'string'
            },
        ],
        'nextToken': 'string'
    }

    """
    pass


def rewrite_ref(identifier, base_url):
    """
    The refs in the schemas are arbitrary identifiers, and cannot be used as-is as real network locations.
    This rewrites any of those arbitrary refs to be real urls servable by this endpoint.
    """
    if not base_url.endswith('/'):
        base_url += '/'
    if identifier.startswith('/schema/'):
        return base_url + identifier[1:]
    return identifier


def setState(state):
    """Set workflow state for this object.
        """


def prox_sum_squares_base(v, t):
    """Proximal operator of :math:`f(x) = \\sum_i x_i^2`.
    """
    return v / (1.0 + 2 * t)


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

        :param AccountLockOrUnlockedDetails val:
        :rtype: EventDetails
        """
    return cls('account_lock_or_unlocked_details', val)


@classmethod
def register_node(cls, node):
    """
        Register a node that was scheduled
        :param node: flow to be tracked
        """
    from celery.result import AsyncResult
    from selinon.dispatcher import Dispatcher
    if isinstance(node, Dispatcher):
        cls._flow_instances.append(node)
    else:
        cls._task_instances.append(node)
    AsyncResult.set_unfinished(node.task_id)


@classmethod
def get_fault(cls, session, extension=''):
    """
        Gets the fault that is pending for this class.  Faults are
        returned in the form of objects.  Objects that have been deleted
        are marked as such.

        :param session:  the instance of Session used for APIC communication
        """
    urls = cls._get_subscription_urls(extension)
    for url in urls:
        if not session.has_events(url):
            continue
        event = session.get_event(url)
        for class_name in cls._get_apic_classes():
            if class_name in event['imdata'][0]:
                break
        attributes = event['imdata'][0]
        return attributes


def qefsr(wavelength, spectral_response):
    """convert SR (A/W) to QE (unit 0 to 1)
    assumes that the wavelegth is in  nm"""
    QE = spectral_response * wavelength / 1239.8
    return QE


def ar2rc(ar):
    """ Convert autoregressive parameters into reflection coefficients """
    raise NotImplementedError


def get_sessions(client, project, subject=None, session=None):
    """Query the flywheel client for a project name
    This function uses the flywheel API to find the first match of a project
    name. The name must be exact so make sure to type it as is on the
    website/GUI.
    Parameters
    ---------
    client
        The flywheel Client class object.
    project
        The name of the project to search for.
    subject
        Subject ID
    session
        Session ID

    Returns
    ---------
    seq_infos
        A list of SeqInfo objects
    """
    project_object = client.projects.find_first('label={0}'.format(project))
    context = {'project': project_object}
    if project_object is None:
        print('Available projects are:\n')
        for p in client.projects():
            print('%s' % p.label)
        raise ValueError('Could not find "{0}" project on Flywheel!'.format
            (project))
    if subject is not None:
        subject = project_object.subjects.find_one('code="{}"'.format(subject))
        sessions = subject.sessions()
    elif session is not None:
        sessions = project_object.sessions.find('label="{}"'.format(session))
    else:
        sessions = project_object.sessions()
    return sessions


def enabled():
    """
        Lets you know if the flowview is enabled
        """


def supplements(parms, countrate=None):
    u"""Supplementary parameters:
        Effective number of freely diffusing particles in 3D solution:
        [11] n3D = n*F
        Effective number particles diffusing on 2D surface:
        [12] n2D = n*(1-F)
    """
    n = parms[0]
    F3d = parms[3]
    Info = list()
    Info.append([u'n3D', n * F3d])
    Info.append([u'n2D', n * (1.0 - F3d)])
    if countrate is not None:
        cpp = countrate / n
        Info.append([u'cpp [kHz]', cpp])
    return Info


@classmethod
def __list_fields(cls):
    """
        Get all the fields defined for our class, if we have an Index, try
        looking at the index mappings as well, mark the fields from Index as
        optional.
        """
    for name in cls._doc_type.mapping:
        field = cls._doc_type.mapping[name]
        yield name, field, False
    if hasattr(cls.__class__, '_index'):
        if not cls._index._mapping:
            return
        for name in cls._index._mapping:
            if name in cls._doc_type.mapping:
                continue
            field = cls._index._mapping[name]
            yield name, field, True


def _newnames(datatype, order):
    """
    Given a datatype and an order object, return a new names tuple, with the
    order indicated
    """
    oldnames = datatype.names
    nameslist = list(oldnames)
    if isinstance(order, str):
        order = [order]
    seen = set()
    if isinstance(order, (list, tuple)):
        for name in order:
            try:
                nameslist.remove(name)
            except ValueError:
                if name in seen:
                    raise ValueError('duplicate field name: %s' % (name,))
                else:
                    raise ValueError('unknown field name: %s' % (name,))
            seen.add(name)
        return tuple(list(order) + nameslist)
    raise ValueError('unsupported order value: %s' % (order,))


@staticmethod
def cache_clear(obj):
    """
        Clears the cache and frees memory (GC?)
        :param obj:
        """
    obj._cache = {}
    obj._mutated = False


def calc_M20(peaks, HKL, ifX20=True):
    """needs a doc string"""
    diff = 0
    X20 = 0
    for Nobs20, peak in enumerate(peaks):
        if peak[3]:
            Qobs = 1.0 / peak[7] ** 2
            Qcalc = 1.0 / peak[8] ** 2
            diff += abs(Qobs - Qcalc)
        elif peak[2]:
            X20 += 1
        if Nobs20 == 19:
            d20 = peak[7]
            break
    else:
        d20 = peak[7]
        Nobs20 = len(peaks)
    for N20, hkl in enumerate(HKL):
        if hkl[3] < d20:
            break
    Q20 = 1.0 / d20 ** 2
    if diff:
        M20 = Q20 / (2.0 * diff)
    else:
        M20 = 0
    if ifX20:
        M20 /= 1.0 + X20
    return M20, X20


def _get_blank_value_18(field):
    """Get the value for blank fields in Django 1.8 and earlier."""
    if field.null:
        return None
    else:
        return field.value_to_string(None)


@classmethod
def parse(cls, reader):
    """returns this metadata block from a BitstreamReader"""
    values = reader.parse('16u16u24u24u20u3u5u36U16b')
    values[5] += 1
    values[6] += 1
    return cls(*values)


def lang(name, comment_symbol, multistart=None, multiend=None):
    """
    Generate a language entry dictionary, given a name and comment symbol and
    optional start/end strings for multiline comments.
    """
    result = {'name': name, 'comment_symbol': comment_symbol}
    if multistart is not None and multiend is not None:
        result.update(multistart=multistart, multiend=multiend)
    return result


def uninstall(context):
    """Uninstall script"""
    if context.readDataFile('collectiverelatedslider_uninstall.txt') is None:
        return


def _d_g(d_h: float, d_s: float, temp: float) ->float:
    """Find the free energy given delta h, s and temp

    Args:
        d_h: The enthalpy increment in kcal / mol
        d_s: The entropy increment in cal / mol
        temp: The temperature in Kelvin

    Returns:
        The free energy increment in kcal / (mol x K)
    """
    return d_h - temp * (d_s / 1000.0)


@classmethod
def configured_class(cls):
    """Returns the currently configured class."""
    base = cls.configurable_base()
    if base.__dict__.get('_Configurable__impl_class') is None:
        base.__impl_class = cls.configurable_default()
    return base.__impl_class


@staticmethod
def startDiagram(*args):
    """ Called first during the render to initialise a diagram """
    pass


def exclude(func):
    """Return the opposite of ``func`` (i.e. ``False`` instead of ``True``)"""
    return lambda x: not func(x)


def process(proc_data):
    """
    Final processing to conform to the schema.

    Parameters:

        proc_data:   (dictionary) raw structured data to process

    Returns:

        List of dictionaries. Structured data with the following schema:

        [
          {
            "listen":       string,
            "unit":         string,
            "activates":    string
          }
        ]
    """
    return proc_data


def count_simulation_problem_batches(n_simulation_problem_chunks,
    n_simulation_problems, n_simulation_problem_batches_per_chunk):
    """
    Count batches to be generated.

    :param n_simulation_problem_chunks: number of chunks of simulation problems
    :param n_simulation_problems: number of simulations to perform
    :param n_simulation_problem_batches_per_chunk: number of batches to evenly split each chunk into
    :return: number of batches
    """
    return min(n_simulation_problem_chunks *
        n_simulation_problem_batches_per_chunk, n_simulation_problems)


def addGroup(id, **kw):
    """
        Create a group with the supplied id, roles, and groups.
        return True if the operation suceeded
        """


def addOutputLevel(parser):
    """
    Add options to get more or less messages.
    """
    if hasattr(parser, 'add_option'):
        from .options_old import addOutputLevel
        return addOutputLevel(parser)
    import logging
    parser.add_argument('--verbose', action='store_const', const=logging.
        INFO, dest='log_level', help='print more information')
    parser.add_argument('--debug', action='store_const', const=logging.
        DEBUG, dest='log_level', help='print debug messages')
    parser.add_argument('--quiet', action='store_const', const=logging.
        WARNING, dest='log_level', help='print only warning messages (default)'
        )
    parser.set_defaults(log_level=logging.WARNING)
    return parser


def get_glyphs_from_file(file_name):
    """Obtain the glyphs that want to be kept from a line seperated file"""
    with open(file_name, 'r') as file:
        return file.read().splitlines()


@staticmethod
def check_required_params(params: dict, payload: dict):
    """
			Vérifie que la paramètres requis soient bien présents dans la charge utile.
			Lance une erreur spécifique le cas contraire.
		"""
    for par in params:
        if 'required' in params[par]:
            if params[par]['required']:
                if par not in payload:
                    raise ValueError('Required argument not provided : ' + par)


def reject_axis(vector, axis, squash=False):
    """
    Compute the vector component of `vector` perpendicular to the basis
    vector specified by `axis`. 0 means x, 1 means y, 2 means z.

    In other words, return a copy of vector that zeros the `axis` component.

    When `squash` is True, instead of zeroing the component, it drops it, so
    an input vector (in R3) is mapped to a point in R2.

    (N.B. Don't be misled: this meaning of `axis` is pretty different from
    the typical meaning in numpy.)

    """
    if squash:
        dims_to_keep = [0, 1, 2]
        try:
            dims_to_keep.remove(axis)
        except ValueError:
            raise ValueError('axis should be 0, 1, or 2')
        if vector.ndim == 1:
            return vector[dims_to_keep]
        elif vector.ndim == 2:
            return vector[:, (dims_to_keep)]
        else:
            raise ValueError('Not sure what to do with %s dimensions' %
                vector.ndim)
    else:
        result = vector.copy()
        if vector.ndim == 1:
            result[axis] = 0.0
        elif vector.ndim == 2:
            result[:, (axis)] = 0.0
        else:
            raise ValueError('Not sure what to do with %s dimensions' %
                vector.ndim)
        return result


@classmethod
def from_key(cls, key):
    """
        Returns the enum instance for the given string key.
        """
    keymap = cls._get_key_cache()
    try:
        return keymap[key]
    except KeyError:
        raise KeyError('Key "{}" not found in enum "{}"'.format(key, cls.
            __name__)) from None


def get_shape(shape):
    """Return rows, columns for the shape."""
    try:
        return (shape[0], shape[1]) + shape[2:]
    except IndexError:
        return (shape[0], 0) + shape[2:]
    except TypeError:
        return int(shape), 0