def combine_split_NM_lines(nm, data_lines):
    """
    combine split lines of data

        #N N [M]

    Indicates there are N columns of data.
    If M is present, it indicates there
    are M sets of data columns on each line.
    """
    if len(nm) == 1:
        return data_lines
    dl = []
    N, M = nm
    buf = ''
    for line in data_lines:
        if line.startswith('@A'):
            if len(buf) > 0:
                dl.append(buf)
            buf = []
            dl.append(line)
        else:
            if len(buf) > 0 and buf[-1] != ' ':
                buf += ' '
            buf += line
            if len(buf.split()) == N:
                dl.append(buf)
                buf = ''
    return dl


def read_py(f):
    """read as python struct."""
    dict_ = eval(open(f).read())
    return dict_


def parse_version(version: str) ->tuple:
    """Parse a string formatted X[.Y.Z] version number into a tuple

    >>> parse_version('10.2.3')
    (10, 2, 3)

    >>> parse_version('12')
    (12, 0, 0)
    """
    parts = version.split('.')
    missing = 3 - len(parts)
    return tuple(map(int, parts + ['0'] * missing))


@conf
def find_pgfortran(conf):
    """Find the PGI fortran compiler (will look in the environment variable 'FC')"""
    fc = conf.find_program(['pgfortran', 'pgf95', 'pgf90'], var='FC')
    conf.get_pgfortran_version(fc)
    conf.env.FC_NAME = 'PGFC'


def _is_aware(value):
    """
    Determines if a given datetime.time is aware.

    The logic is described in Python's docs:
    http://docs.python.org/library/datetime.html#datetime.tzinfo
    """
    return value.tzinfo is not None and value.tzinfo.utcoffset(value
        ) is not None


def normalize_hostname(hostname):
    """Strips the FQDN from the hostname, since hostname is unique in MAAS."""
    if hostname:
        return hostname.split('.', 1)[0]
    return hostname


@staticmethod
def is_supported_action(action):
    """ Returns True if the given action is supported. """
    return action in {'new', 'paste', 'edit', 'delete'}


def brightness(value):
    """Brightness of the light. This is a scale from the minimum brightness the
    light is capable of, 1, to the maximum capable brightness, 254."""
    value = int(value)
    if value < 1 or value > 254:
        raise ValueError('Minimum brightness is 1, to the maximum 254')
    return value


def IS(instance, other):
    """
    Support the `future is other` use-case.
    Can't override the language so we built a function.
    Will work on non-future objects too.

    :param instance: future or any python object
    :param other: object to compare.
    :return:
    """
    try:
        instance = instance._redpipe_future_result
    except AttributeError:
        pass
    try:
        other = other._redpipe_future_result
    except AttributeError:
        pass
    return instance is other


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


@classmethod
def launch_instance(cls, argv=None, **kwargs):
    """Launch a global instance of this Application

        If a global instance already exists, this reinitializes and starts it
        """
    app = cls.instance(**kwargs)
    app.initialize(argv)
    app.start()


def bc_robin(matrix_lhs, matrix_rhs, positions, grad_n_bc, a_val, b_val, c_val
    ):
    """
    Function to enforce the Boundary Condition in the Robin formalism:

                    a * (df / dn) + b * f + c = O

    Parameters
    ----------
    matrix_lhs: Left Hand Side square matrix (shape (size_i_w * size_j_ns)^2)
    matrix_rhs: Right Hand Side vector (shape (size_i_w * size_j_ns))
    positions: indices of lines corresponding to the patch being processed
    grad_n_bc: normal gradient to boundary nodes
    a_val: value of the "a" Robin parameter
    b_val: value of the "b" Robin parameter
    c_val: value of the "a" Robin parameter

    Returns
    -------
    Altered left-hand side matrix and right-hand side vector
    """
    for row in positions:
        if grad_n_bc.count_nonzero():
            matrix_lhs[(row), :] = a_val * grad_n_bc[(row), :]
        matrix_lhs[row, row] += b_val
    matrix_rhs[positions] = -c_val
    return matrix_lhs, matrix_rhs


def group_remove():
    """Remove the active object from this group

    """
    pass


def dim(string):
    """Return string with gray ansicolor coding."""
    return '\x1b[37m\x1b[22m' + string + '\x1b[0m'


def encode_var_int(number):
    """
	Returns a bytearray encoding the given number.
	"""
    buf = bytearray()
    shift = 1
    while True:
        buf.append(number & 127)
        number -= buf[-1]
        if number == 0:
            buf[-1] |= 128
            break
        number -= shift
        number >>= 7
        shift += 7
    return buf


def load_jsonl(filename):
    """Load json lines formatted file"""
    import json
    with open(filename, 'r') as f:
        return list(map(json.loads, f))


def is_empty(dict_obj):
    """
    query if a dict is empty

    :param dict_obj: the to be tested dictionary
    :return: True, if it is empty, False if not empty
    """
    if isinstance(dict_obj, dict):
        if len(list(dict_obj.items())) <= 0:
            return True
        else:
            switch = True
            for k, v in list(dict_obj.items()):
                if v is None:
                    pass
                else:
                    switch = False
            return switch
    else:
        return False


def getPolicyMap():
    """Return a mapping of types to the lists of policies they support,
           for use in config screen."""


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


def vertices_smooth(factor: float=0.5, repeat: int=1, xaxis: bool=True,
    yaxis: bool=True, zaxis: bool=True):
    """Flatten angles of selected vertices

    :param factor: Smoothing, Smoothing factor
    :type factor: float
    :param repeat: Repeat, Number of times to smooth the mesh
    :type repeat: int
    :param xaxis: X-Axis, Smooth along the X axis
    :type xaxis: bool
    :param yaxis: Y-Axis, Smooth along the Y axis
    :type yaxis: bool
    :param zaxis: Z-Axis, Smooth along the Z axis
    :type zaxis: bool
    """
    pass


def atom_num_radical_electrons(atom):
    """Get the number of radical electrons for an atom.

    Parameters
    ----------
    atom : rdkit.Chem.rdchem.Atom
        RDKit atom instance.

    Returns
    -------
    list
        List containing one int only.

    See Also
    --------
    atom_num_radical_electrons_one_hot
    """
    return [atom.GetNumRadicalElectrons()]


def axis_conversion(from_forward='Y', from_up='Z', to_forward='Y', to_up='Z'):
    """Each argument us an axis in [‘X’, ‘Y’, ‘Z’, ‘-X’, ‘-Y’, ‘-Z’] where the first 2 are a source and the second 2 are the target.

    """
    pass


def positive_real_zero(var, var_name):
    """
    Check if parameter *var* is a positive number or zero.

    :raises TypeError: Parameter *var* must be a real number.
    :raises ValueError: Parameter *var* must be a positive number or zero.
    """
    if not isinstance(var, (int, float)):
        raise TypeError('\n\nParameter {} must be a real number.\n'.format(
            var_name))
    if var < 0:
        raise ValueError(
            '\n\nParameter {} must be a positive number  or zero.\n'.format
            (var_name))


def level_to_power(level):
    """
    Converts logarithmic sound pressure level value (dB)
    to metric power value (W/m^2)
    """
    return pow(10.0, float(level) / 10.0) * 1e-12


def track_to_json(pyTrack, manager):
    """Serialize a Track.
    Attributes of this dictionary are to be passed to the JavaScript Date
    constructor.

    Args:
        :param Track: Track object
        :param any: manager. Used for widget serialization.

    Returns:
        dict of Track elements (viz, source, sourceOptions and label)

    """
    if pyTrack is None:
        return None
    else:
        return dict(viz=pyTrack.viz, source=pyTrack.source, sourceOptions=
            pyTrack.sourceOptions, label=pyTrack.label)


def Calc_instantaneous_ET_fraction(LE_inst, rn_inst, g_inst):
    """
    Function to calculate the evaporative fraction
    """
    EF_inst = LE_inst / (rn_inst - g_inst)
    EF_inst = EF_inst.clip(0.0, 1.8)
    EF_inst[LE_inst < 0] = 0
    return EF_inst


@staticmethod
def get_opt(opt_name, args):
    """Return option name and value.

        :param opt_name: name of the option, e.g., "username"
        :param args: parsed arguments
        """
    return opt_name, getattr(args, 'os_%s' % opt_name, None)


@classmethod
def copy_dataset(cls, gdal_dataset, **kwargs):
    """Create VRT with bands and georefernce as a full copy of input GDAL Dataset

        Parameters
        ----------
        gdal_dataset : GDAL.Dataset
            input dataset
        **kwargs : dict
            arguments for VRT()

        Returns
        -------
        vrt : VRT

        """
    vrt = cls.__new__(cls)
    vrt._copy_from_dataset(gdal_dataset, **kwargs)
    return vrt


def grayscale(image):
    """
    Convert the image to grayscale.

    :param image: The image to convert.
    :return: An image.
    """
    return image.convert('L')


def set_ime(ime_name, toolkit=None):
    """
    设置输入法（需要使用adb shell ime list -a 获取输入法包名）

    :param ime_name: 输入法包名 eg：com.android.inputmethod.pinyin/.PinyinIME
    :param toolkit:
    :return:
    """
    return toolkit.adb.run(['shell', 'ime', 'set', ime_name])


def post_install(context):
    """Post install script"""


def _exception_message(excp):
    """Return the message from an exception as either a str or unicode object.  Supports both
    Python 2 and Python 3.

    >>> msg = "Exception message"
    >>> excp = Exception(msg)
    >>> msg == _exception_message(excp)
    True

    >>> msg = u"unicöde"
    >>> excp = Exception(msg)
    >>> msg == _exception_message(excp)
    True
    """
    if hasattr(excp, 'message'):
        return excp.message
    return str(excp)


@classmethod
def set_class_path(cls, path):
    """Set class path attribute."""
    cls._path = path


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 _specialized_from_args(signatures, args, kwargs):
    """Perhaps this should be implemented in a TreeFragment in Cython code"""
    raise Exception('yet to be implemented')


def check_partial_index(n_samples, test_size, train_size, n_test, n_train):
    """Check that folds can be constructed from passed arguments."""
    if n_test + n_train > n_samples:
        raise ValueError(
            'The selection of train (%r) and test (%r) samples lead to a subsets greater than the number of observations (%i). Implied test size: %i, implied train size: %i.'
             % (test_size, train_size, n_samples, n_test, n_train))
    for n, i, j in zip(('test', 'train'), (n_test, n_train), (test_size,
        train_size)):
        if n == 0:
            raise ValueError(
                'The %s set size is 0 with current selection (%r): cannot create %s subset. Assign a greater proportion of samples to the %s set (total samples size: %i).'
                 % (i, j, i, i, n_samples))
    if n_samples < 2:
        raise ValueError('Sample size < 2: nothing to create subset from.')


def draw_footnote(fig, string, fontsize=9):
    """Draw footnote on a figure"""
    ax = fig.add_axes([0.0, 0.0, 1.0, 1.0])
    ax.text(0.5, 0.01, string, horizontalalignment='center', fontsize=fontsize)
    ax.patch.set_alpha(0.0)
    ax.set_axis_off()
    return ax


def cast_vanilla(value, cur):
    """Vanilla Type caster for psycopg2

    Simply returns the string representation.
    """
    if value is None:
        return None
    else:
        return str(value)


@staticmethod
def get_highdim(dtype=None):
    """
        Return mapping for high dimensional classes.  Return only for datatype
        if dtype is set.  Else return full map.

        :param dtype: optional datatype (e.g. cnv)
        :return: dict with mapping, or class.
        """
    from ..highdim.CopyNumberVariation import CopyNumberVariation
    from ..highdim.ReadCounts import ReadCounts
    from ..highdim.Expression import Expression
    from ..highdim.Mirna import Mirna
    from ..highdim.Proteomics import Proteomics
    map_d = {'rnaseq': ReadCounts, 'cnv': CopyNumberVariation, 'expression':
        Expression, 'proteomics': Proteomics, 'mirna': Mirna}
    if dtype:
        return map_d[dtype]
    else:
        return map_d


def apply_rect_mask_to_layer(source, alpha):
    """ Same as apply_mask_to_layer(), but for single pixels. Also always uses black background,
        since it's for greyscale masks.
    """
    dest = 0
    if alpha == 0:
        return dest
    if alpha == 255:
        return source
    alpha_pct = alpha / 255.0
    new_rgb = int(source * alpha_pct + dest * (1 - alpha_pct))
    return new_rgb


def regroupOptionsByName(options):
    """
    Regroupe les option d'une liste par nom

    Args:
        options: La liste d'option
    Returns:
        Liste d'option groupe
    """
    groupedOptions = []
    groups = {}
    for option in options:
        groups.setdefault(option.name, list()).append(option)
    for key in groups:
        if len(groups[key]) > 1:
            groupedOptions.append(groups[key])
        else:
            groupedOptions.append(groups[key].pop())
    return groupedOptions


def case_3_0(node):
    """ Case when node have two children, one
    of which is brackets, other not (W->[a, )] or E->[(, a]).
    In that case it transform from:
    T->['(', H->[X, ')']]
    to
    br->['(', args->[X], ')']
    !Right branch is alvays second (from buttom)"""
    parent = node.parent
    grandparent = parent.parent
    br_r_node = node.find_br_child()
    node.remove_child(br_r_node)
    parent.add_child(br_r_node)
    node.name = 'args'
    node.visited = True
    parent.name = 'br'
    parent.visited = True
    if grandparent is not None:
        return grandparent
    else:
        return parent


def translateDiatonicStreamToString(inputStreamOrIterator, returnMeasures=False
    ):
    """
    Translates a Stream or StreamIterator of Notes and Rests only into a string,
    encoding only the .step (no accidental or octave) and whether
    the note is slower, faster, or the same speed as the previous
    note.

    Skips all but the first note of tie. Skips multiple rests in a row

    Each note gets one byte:

    A-G = note of same length as previous
    H-N = note of longer length than previous
    O-U = note of shorter length than previous
    Z = rest

    >>> s = converter.parse("tinynotation: 3/4 c4 d8~ d16 r16 FF8 F#8 a'8 b-2.")
    >>> streamString = search.translateDiatonicStreamToString(s.recurse().notesAndRests)
    >>> print(streamString)
    CRZFFAI
    >>> len(streamString)
    7

    If returnMeasures is True, returns an array of measureNumbers where each entry represents
    the measure number of the measure of the object at that character position :

    >>> streamString2, measures = search.translateDiatonicStreamToString(s.recurse().notesAndRests,
    ...                                    returnMeasures=True)
    >>> streamString == streamString2
    True
    >>> measures
    [1, 1, 1, 1, 1, 2, 2]
    """
    b = []
    measures = []
    previousRest = False
    previousTie = False
    previousQL = None
    for n in inputStreamOrIterator:
        mNum = None
        if returnMeasures:
            mNum = n.measureNumber
        if n.isRest:
            if previousRest is True:
                continue
            else:
                previousRest = True
                b.append('Z')
                measures.append(mNum)
                continue
        else:
            previousRest = False
        if previousTie is True:
            if n.tie is None or n.tie.type == 'stop':
                previousTie = False
            continue
        elif n.tie is not None:
            previousTie = True
        ql = n.duration.quarterLength
        if previousQL is None or previousQL == ql:
            ascShift = 0
        elif previousQL > ql:
            ascShift = 14
        else:
            ascShift = 7
        previousQL = ql
        newName = chr(ord(n.pitches[0].step) + ascShift)
        measures.append(mNum)
        b.append(newName)
    joined = ''.join(b)
    if returnMeasures is False:
        return joined
    else:
        return joined, measures


def _build_args(name, meta, context, pass_context=False):
    """
    Builds parameters to pass to resource_type handler.
    Default parameters dict consists of name and meta keys.
    If pass_context set to True, parameters dict is extended with 'context' key
    :param name: name of the resource
    :param meta: definition of the resource
    :param context: result of previously deployed resources in scope of current syndicate execution
    :param pass_context: flag. Manages if output will be included to parameters
    :return: prepared parameters to be passed to resource_type handler.
    """
    params = {'name': name, 'meta': meta}
    if pass_context:
        params['context'] = context
    return params


def set_analog_src(lucid, srcval):
    """Call lucid8824.set_analog_src"""
    lucid.set_analog_src(srcval)


def get_int_arg(r, name, default=None):
    """
    Retrieve argument from :attr:`flask:flask.request` and convert to integer

    :param r: :attr:`flask:flask.request`
    :param name: argument name
    :type: str
    :param default: default value if parameter is non-existent, defaults to None
    :return: integer argument value
    """
    val = r.args.get(name)
    if val is None or val == '':
        return default
    else:
        try:
            return int(val)
        except BaseException:
            return default


@staticmethod
def sgr_fg_rgb(r, g, b):
    """Get SGR (Set Graphics Rendition) foreground RGB color."""
    return '38;2;{};{};{}'.format(r, g, b)


def normals_make_consistent(calc_length: bool=False):
    """Recalculate the direction of selected handles

    :param calc_length: Length, Recalculate handle length
    :type calc_length: bool
    """
    pass


@classmethod
def register_dimension(cls, name, base_unit):
    """
        Register a new dimension along with its base unit.

        Parameters
        ----------
        name : unicode
            The name of the dimension.
        base_unit : unicode
            The identifier of the dimension's base unit.

        Raises
        ------
        ValueError
            If the given dimension already exists.
        """
    if name in cls._defaults_per_dimension:
        raise ValueError('Dimension %s already exists' % name)
    cls._defaults_per_dimension[name] = base_unit


@classmethod
def bug_id_from_url(cls, url):
    """
            Jira IDs are the last group of chars at the end of the URL.
            For example https://issues.jenkins-ci.org/browse/JENKINS-31044
        """
    return url.strip().split('/')[-1]


def new_sharedStrings_text(db):
    """
    Returns xl/sharedStrings.xml text

    :param pylightxl.Database db: database contains sheetnames, and their data
    :return str: xl/sharedStrings.xml text
    """
    xml_base = (
        '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r\n<sst uniqueCount="{sharedString_len}" count="{sharedString_len}" xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">\r\n{many_tag_si}\r\n</sst>'
        )
    xml_tag_si = '<si><t {space_preserve}>{val}</t></si>\r\n'
    sharedString_len = len(db._sharedStrings)
    many_tag_si = ''
    for val in db._sharedStrings:
        if val[0] == ' ' or val[-1] == ' ':
            space_preserve = 'xml:space="preserve"'
        else:
            space_preserve = ''
        many_tag_si += xml_tag_si.format(space_preserve=space_preserve, val=val
            )
    rv = xml_base.format(sharedString_len=sharedString_len, many_tag_si=
        many_tag_si)
    return rv


def detail_flood_fill():
    """Flood fill the mesh with the selected detail setting

    """
    pass


def get_z_prop(p, pi, n):
    """
    Function to get the Z value (standard deviations number under or over the average)
    correspondent of the x value (parameter) in the standard normal distribution.
    Applied in proportions.

    Parameters:
    --------------------------
    p : double, float
        "Succeses" observations sample proportion.
        Each value should be in the range [0, 1].

    pi : double, float
        Population proportion given.
        Each value should be in the range [0, 1].

    n : int
        Sample size.

    Returns:
    --------------------------
    z : float, double
        The Z value (standard deviations number under or over the average)
        correspondent of the x value (parameter) in the standard normal distribution.
    """
    error = (pi * (1 - pi) / n) ** 0.5
    z = (p - pi) / error
    return z


@staticmethod
def _generate_section_header_md(section_type, title, prepend_newline=True):
    """generates markdown section header."""
    prefix = '\n' if prepend_newline else ''
    return prefix + '## {}:{}\n'.format(section_type, title)


def get_persistent_state(obj, seen):
    """Convert a persistent object to a JSONB state/document."""


def inverse(A):
    """For A affine 2D represented as 6vec return 6vec version of A**(-1)"""
    det = float(A[0] * A[3] - A[2] * A[1])
    R = [A[3] / det, -A[1] / det, -A[2] / det, A[0] / det]
    return tuple(R + [-R[0] * A[4] - R[2] * A[5], -R[1] * A[4] - R[3] * A[5]])


def get_haplotype_score(var):
    """
    Returns consistency of the site with two segregating haplotypes,
    or None if it isn't present in the VCF.
    """
    return var.INFO.get('HaplotypeScore')


def test():
    """Test by comparing analytical and numerical values.

    >>> S =  49
    >>> K = 50
    >>> r = .05
    >>> t = 0.3846
    >>> sigma = 0.2
    >>> flag = 'c'

    >>> epsilon = .0001

    >>> v1 = delta(flag, S, K, t, r, sigma)
    >>> v2 = adelta(flag, S, K, t, r, sigma)
    >>> abs(v1-v2)<epsilon
    True

    >>> v1 = gamma(flag, S, K, t, r, sigma)
    >>> v2 = agamma(flag, S, K, t, r, sigma)
    >>> abs(v1-v2)<epsilon
    True

    >>> v1 = rho(flag, S, K, t, r, sigma)
    >>> v2 = arho(flag, S, K, t, r, sigma)
    >>> abs(v1-v2)<epsilon
    True

    >>> v1 = vega(flag, S, K, t, r, sigma)
    >>> v2 = avega(flag, S, K, t, r, sigma)
    >>> abs(v1-v2)<epsilon
    True

    >>> v1 = theta(flag, S, K, t, r, sigma)
    >>> v2 = atheta(flag, S, K, t, r, sigma)
    >>> abs(v1-v2)<epsilon
    True
    """
    pass


def default_motion_cor_2_v1_1_0():
    """
    Content of MotionCor2 version 1.1.0.

    Arguments:
    None

    Return:
    Content items as list
    """
    items = [['WIDGETS MAIN', '5', int, '', 'PLAIN', '', ''], [
        'WIDGETS ADVANCED', '5', int, '', 'PLAIN', '', ''], ['WIDGETS RARE',
        '5', int, '', 'PLAIN', '', ''], ['-FmDose', '0', float, '', 'PLAIN',
        'Main',
        'Frame dose in e/A^2. If not specified, dose weighting will be skipped.'
        ], ['-PixSize', '0', float, '', 'PLAIN', 'Main',
        'Pixel size in A of input stack in angstrom. If not specified, dose weighting will be skipped.'
        ], ['-kV', '300', float, '', 'PLAIN', 'Main',
        'High tension in kV needed for dose weighting.  Default is 300.'],
        ['-Patch', '0 0 0', [int, int, int], '', 'PLAIN', 'Main',
        '1. It follows by  number of patches in x and y dimensions, and overlapping in percentage of adjacent patches.  2. The default values are 0 0 0, meaning only full-frame based alignment is performed.'
        ], ['-Bft', '500 150', [float, float], '', 'PLAIN', 'Main',
        'B-Factor for alignment, default 100.'], ['-Throw', '0', int, '',
        'PLAIN', 'Main', 'Throw initial number of frames, default is 0'], [
        '-Trunc', '0', int, '', 'PLAIN', 'Main',
        'Truncate last number of frames, default is 0'], ['-Gain', '', str,
        '', 'FILE', 'Main',
        'MRC file that stores the gain reference. If not specified, MRC extended header will be visited to look for gain reference.'
        ], ['-RotGain', '0', int, '', 'PLAIN', 'Main',
        'Rotate gain reference counter-clockwise.  0 - no rotation, default, 1 - rotate 90 degree, 2 - rotate 180 degree, 3 - rotate 270 degree.'
        ], ['-FlipGain', '0', int, '', 'PLAIN', 'Main',
        'Flip gain reference after gain rotation.  0 - no flipping, default, 1 - flip upside down, 2 - flip left right.'
        ], ['-MaskCent', '0 0', [float, float], '', 'PLAIN', 'Advanced',
        'Center of subarea that will be used for alignement, default 0 0 corresponding to the frame center.'
        ], ['-MaskSize', '1 1', [float, float], '', 'PLAIN', 'Advanced',
        'The size of subarea that will be used for alignment, default 1.0 1.0 corresponding full size.'
        ], ['-Iter', '7', int, '', 'PLAIN', 'Advanced',
        'Maximum iterations for iterative alignment, default 5 iterations.'
        ], ['-Tol', '0.5', float, '', 'PLAIN', 'Advanced',
        'Tolerance for iterative alignment, default 0.5 pixel.'], [
        '-PhaseOnly', '0', int, '', 'PLAIN', 'Advanced',
        'Only phase is used in cross correlation.  default is 0, i.e., false.'
        ], ['-StackZ', '0', int, '', 'PLAIN', 'Advanced',
        'Number of frames per stack. If not specified, it will be loaded from MRC header.'
        ], ['-FtBin', '1', float, '', 'PLAIN', 'Advanced',
        'Binning performed in Fourier space, default 1.0.'], ['-InitDose',
        '0', float, '', 'PLAIN', 'Advanced',
        'Initial dose received before stack is acquired'], ['-Group', '1',
        int, '', 'PLAIN', 'Advanced',
        'Group every specified number of frames by adding them together. The alignment is then performed on the summed frames. By default, no grouping is performed.'
        ], ['-FmRef', '-1', int, '', 'PLAIN', 'Advanced',
        'Specify which frame to be the reference to which all other frames are aligned. By default (-1) the the central frame is chosen. The central frame is at N/2 based upon zero indexing where N is the number of frames that will be summed, i.e., not including the frames thrown away.'
        ], ['-DefectFile', '', str, '', 'FILE', 'Advanced',
        '1. Defect file that stores entries of defects on camera.  2. Each entry corresponds to a rectangular region in image.  The pixels in such a region are replaced by neighboring good pixel values.  3. Each entry contains 4 integers x, y, w, h representing the x, y coordinates, width, and heights, respectively.'
        ], ['-Dark', '', str, '', 'FILE', 'Advanced',
        '1. MRC file that stores the dark reference. If not specified, dark subtraction will be skipped.  2. If -RotGain and/or -FlipGain is specified, the dark reference will also be rotated and/or flipped.'
        ], ['-Tilt', '0 0', [float, float], '', 'PLAIN', 'Advanced',
        'Specify the starting angle and the step angle of tilt series. They are required for dose weighting. If not given, dose weighting will be disabled.'
        ], ['-Mag', '1 1 0', [float, float, float], '', 'PLAIN', 'Advanced',
        '1. Correct anisotropic magnification by stretching image along the major axis, the axis where the lower magificantion is detected.  2. Three inputs are needed including magnifications along major and minor axes and the angle of the major axis relative to the image x-axis in degree.  3. By default no correction is performed.'
        ], ['-InFmMotion', '0', int, '', 'PLAIN', 'Advanced',
        '1. 1 - Account for in-frame motion.  0 - Do not account for in-frame motion.'
        ], ['-Crop', '0 0', [int, int], '', 'PLAIN', 'Advanced',
        '1. Crop the loaded frames to the given size.  2. By default the original size is loaded.'
        ], ['-Gpu', '0', [int] * 99, '', 'PLAIN', 'Advanced',
        ' GPU IDs. Default 0.  For multiple GPUs, separate IDs by space.  For example, -Gpu 0 1 2 3 specifies 4 GPUs.'
        ], ['-GpuMemUsage', '0.5', float, '', 'PLAIN', 'Advanced',
        '1. GPU memory usage, default 0.5, meaning 50% of GPU memory will be used to buffer movie frames.  2. The value should be between 0 and 0.5. When 0 is given, all movie frames are buffered on CPU memory.'
        ], ['Split Gpu?', ['True', 'False'], bool, '', 'COMBO', 'Advanced',
        'NOT A CRYOLO OPTION. Split the gpu values specified in --Gpu to be able to run mutliple crYOLO jobs in parallel.'
        ], ['dose cutoff', '4', float, '', 'PLAIN', 'Advanced',
        'NOT A MOTIONCOR OPTION. Used to create the Relion3 bayesian polishing files.'
        ]]
    return items


@staticmethod
def sanitize_bool(value):
    """
        If value is provided, sanitize it.

        'true' will be used if value is in [True, 'true', 'True', 1].
        'false' will be used if value is in [False, 'false', 'False', 0].

        If we receive any other value value will be set to None and
        ignored when building the GET request.

        :param value: The value to sanitize.
        :type value: bool, str, int
        :returns: str, None
        """
    if value in (True, 'true', 'True', 1):
        value = 'true'
    elif value in (False, 'false', 'False', 0):
        value = 'false'
    else:
        value = None
    return value


def _pretty_str(value):
    """
    Return a value of width bits as a pretty string.
    """
    if value is None:
        return 'Undefined'
    return str(value)


def listing():
    """Fetches the corresponding view which renders a listing.
        Called from javascript tabbedview.js in reload_view.
        """


@classmethod
def _is_exposed_column(cls, field):
    """
            Check field is exposed, i.e.
            - not exposed columns
            - column referencing not exposed columns
            - exposure is specified explicitly in "exposed" info dict
            - exposure default to false iff column is primary key
            :return True iff column is exposed
        """
    path = field.split('.')
    cols = cls._get_column(path)
    if not isinstance(cols, list):
        cols = [cols]
    for col in cols:
        for fk in getattr(col, 'foreign_keys', set()):
            is_primary_key = fk.column.primary_key
            fk_table = fk.column.table.name
            assert fk_table.quote is None
            if not fk.column.info.get('exposed', not is_primary_key):
                return False
        if not col.info.get('exposed', not col.primary_key):
            assert col.class_.__table__.name.quote is None
            return False
    return True


@staticmethod
def setup_file_filter(format_filter):
    """
        Used to set up filters for recently used files.
        """
    format_filter.set_name('odML Documents (*.xml, *.yaml, *.json, *.odml)')
    format_filter.add_mime_type('application/xml')
    format_filter.add_mime_type('text/xml')
    format_filter.add_pattern('*.xml')
    format_filter.add_pattern('*.yaml')
    format_filter.add_pattern('*.yml')
    format_filter.add_pattern('*.json')
    format_filter.add_pattern('*.odml')


def to_list(value):
    """Convert a value to list."""
    if type(value) == set | type(value == list):
        return list(value)
    else:
        return [value]


def where(condition=None, x=None, y=None, name=None, attr=None, out=None,
    **kwargs):
    """Return the elements, either from x or y, depending on the condition.

    Given three ndarrays, condition, x, and y, return an ndarray with the elements from x or y,
    depending on the elements from condition are true or false. x and y must have the same shape.
    If condition has the same shape as x, each element in the output array is from x if the
    corresponding element in the condition is true, and from y if false.

    If condition does not have the same shape as x, it must be a 1D array whose size is
    the same as x's first dimension size. Each row of the output array is from x's row
    if the corresponding element from condition is true, and from y's row if false.

    Note that all non-zero values are interpreted as ``True`` in condition.

    Examples::

      x = [[1, 2], [3, 4]]
      y = [[5, 6], [7, 8]]
      cond = [[0, 1], [-1, 0]]

      where(cond, x, y) = [[5, 2], [3, 8]]

      csr_cond = cast_storage(cond, 'csr')

      where(csr_cond, x, y) = [[5, 2], [3, 8]]

    Defined in src/operator/tensor/control_flow_op.cc:L57

    Parameters
    ----------
    condition : Symbol
        condition array
    x : Symbol
    y : Symbol

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

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


def success(data):
    """Handle sucessful submition

        This method is called when the action was submitted and the
        submitted data was valid.
        """


def mtf_ts_extractor(mtf, freqs):
    """Extract the T and S MTF from a PSF object.

    Parameters
    ----------
    mtf : `MTF`
        MTF object
    freqs : iterable
        set of frequencies to extract

    Returns
    -------
    tan : `numpy.ndarray`
        array of tangential MTF values
    sag : `numpy.ndarray`
        array of sagittal MTF values

    """
    tan = mtf.exact_tan(freqs)
    sag = mtf.exact_sag(freqs)
    return tan, sag


def _df_to_vector(distance_matrix, df, column):
    """Return a grouping vector from a ``DataFrame`` column.

    Parameters
    ----------
    distance_marix : DistanceMatrix
        Distance matrix whose IDs will be mapped to group labels.
    df : pandas.DataFrame
        ``DataFrame`` (indexed by distance matrix ID).
    column : str
        Column name in `df` containing group labels.

    Returns
    -------
    list
        Grouping vector (vector of labels) based on the IDs in
        `distance_matrix`. Each ID's label is looked up in the ``DataFrame``
        under the column specified by `column`.

    Raises
    ------
    ValueError
        If `column` is not in the ``DataFrame``, or a distance matrix ID is
        not in the ``DataFrame``.

    """
    if column not in df:
        raise ValueError("Column '%s' not in DataFrame." % column)
    grouping = df.reindex(distance_matrix.ids, axis=0).loc[:, (column)]
    if grouping.isnull().any():
        raise ValueError(
            'One or more IDs in the distance matrix are not in the data frame.'
            )
    return grouping.tolist()


@staticmethod
def module_repr(module):
    """Return repr for the module.

        The method is deprecated.  The import machinery does the job itself.

        """
    return '<module {!r} (built-in)>'.format(module.__name__)


def now():
    """
    @api {post} /map/weather/now实况天气
    @apiVersion 1.0.0
    @apiGroup Weather
    @apiDescription 实况天气

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

    @apiSuccess (Success) {Object} basic 基础信息
    @apiSuccess (Success) {String} basic.location 地区／城市名称
    @apiSuccess (Success) {String} basic.cid 地区／城市ID
    @apiSuccess (Success) {String} basic.lat 地区／城市纬度
    @apiSuccess (Success) {String} basic.lon 地区／城市经度
    @apiSuccess (Success) {String} basic.parent_city 该地区／城市的上级城市
    @apiSuccess (Success) {String} basic.admin_area 该地区／城市所属行政区域
    @apiSuccess (Success) {String} basic.cnty 该地区／城市所属国家名称
    @apiSuccess (Success) {String} basic.tz 该地区／城市所在时区
    @apiSuccess (Success) {Object} update 接口更新时间
    @apiSuccess (Success) {String} update.loc 当地时间，24小时制，格式yyyy-MM-dd HH:mm
    @apiSuccess (Success) {String} update.utc UTC时间，24小时制，格式yyyy-MM-dd HH:mm
    @apiSuccess (Success) {String} status 接口状态
    @apiSuccess (Success) {Object} now 实况天气
    @apiSuccess (Success) {String} now.fl 体感温度，默认单位：摄氏度
    @apiSuccess (Success) {String} now.tmp 温度，默认单位：摄氏度
    @apiSuccess (Success) {String} now.cond_code 实况天气状况代码
    @apiSuccess (Success) {String} now.cond_txt 实况天气状况描述
    @apiSuccess (Success) {String} now.wind_deg 风向360角度
    @apiSuccess (Success) {String} now.wind_dir 风向
    @apiSuccess (Success) {String} now.wind_sc 风力
    @apiSuccess (Success) {String} now.wind_spd 风速，公里/小时
    @apiSuccess (Success) {String} now.hum 相对湿度
    @apiSuccess (Success) {String} now.pcpn 降水量
    @apiSuccess (Success) {String} now.pres 大气压强
    @apiSuccess (Success) {String} now.vis 能见度，默认单位：公里
    @apiSuccess (Success) {String} now.cloud 云量

    @apiSuccessExample {json} Success-Response:
    {
        "data": [
            {
                "basic": {
                    "cid": "CN101020500",
                    "location": "嘉定",
                    "parent_city": "上海",
                    "admin_area": "上海",
                    "cnty": "中国",
                    "lat": "31.38352394",
                    "lon": "121.25033569",
                    "tz": "+8.00"
                },
                "update": {
                    "loc": "2018-07-17 13:48",
                    "utc": "2018-07-17 05:48"
                },
                "status": "ok",
                "now": {
                    "cloud": "75",
                    "cond_code": "101",
                    "cond_txt": "多云",
                    "fl": "34",
                    "hum": "53",
                    "pcpn": "0.0",
                    "pres": "1008",
                    "tmp": "33",
                    "vis": "35",
                    "wind_deg": "105",
                    "wind_dir": "东南风",
                    "wind_sc": "3",
                    "wind_spd": "15"
                }
            }
        ]
    }
    """


def _preempt_logging_mods():
    """Preempt known logging mods.

    Some modules modify logging without respecting previous config
    (e.g. absl.logging). This function preempts those changes so that
    our config is applied afterward.
    """
    try:
        import absl.logging as _
    except Exception:
        pass


def convert_UserProperty(model, prop, kwargs):
    """Returns a form field for a ``db.UserProperty``."""
    return None


def _unprotected_volume_from_shape(z):
    """
    Computes the Bloch-Wigner dilogarithm for z assuming z is of a type that
    properly supports polylog.
    """
    return (1 - z).arg() * z.abs().log() + z.polylog(2).imag()


def fname_bits(fname):
    """Return the filter and exposure from standard file name of an object.

    'NGC1000_V_1000_0.fits' gives ('V', '1000').
    """
    pieces = fname.split('.fit')[0].split('_')
    return pieces[-3], pieces[-2]


def mod9710(iban):
    """
    Calculates the MOD 97 10 of the passed IBAN as specified in ISO7064.

    @method mod9710
    @param {String} iban
    @returns {Number}
    """
    remainder = iban
    block = None
    while len(remainder) > 2:
        block = remainder[:9]
        remainder = str(int(block) % 97) + remainder[len(block):]
    return int(remainder) % 97


def get_application():
    """Helper function. Needed for easier testing"""
    from .models import APPLICATION
    return APPLICATION


def _basis2name(basis):
    """
    converts the 'basis' into the proper name.
    """
    component_name = ('DC' if basis == 'diffmap' else 'tSNE' if basis ==
        'tsne' else 'UMAP' if basis == 'umap' else 'PC' if basis == 'pca' else
        basis.replace('draw_graph_', '').upper() if 'draw_graph' in basis else
        basis)
    return component_name


def del_property(id):
    """ Deletes the property with the specified id
        """


def to_marshallable_type(obj):
    """
    Helper for converting an object to a dictionary only if it is not
    dictionary already or an indexable object nor a simple type
    """
    if obj is None:
        return None
    if hasattr(obj, '__marshallable__'):
        return obj.__marshallable__()
    if hasattr(obj, '__getitem__'):
        return obj
    return dict(obj.__dict__)


def eval(image, *args):
    """Evaluate image expression"""
    return image.point(args[0])


def get_exit_code(matches):
    """ Determine exit code """
    exit_code = 0
    for match in matches:
        if match.rule.id[0] == 'I':
            exit_code = exit_code | 8
        elif match.rule.id[0] == 'W':
            exit_code = exit_code | 4
        elif match.rule.id[0] == 'E':
            exit_code = exit_code | 2
    return exit_code


def read_pid_stat(pid='self'):
    """
    Returns system process stat information.

    :param pid: The process ID.
    :returns: The system stat information.
    :rtype: dict
    """
    with open('/proc/%s/stat' % (pid,), 'rb') as f:
        stat = f.readline().split()
    return {'utime': int(stat[13]), 'stime': int(stat[14]), 'cutime': int(
        stat[15]), 'cstime': int(stat[16])}


def principal_permission_grant(principal, permission):
    """Return the principal-permission grant if any

        The return value is one of Allow, Deny, or Unset
        """


def get_package(path_to_module):
    """Return (work_dir, package_name, module_name)."""
    if path_to_module.endswith('.py'):
        path_to_module[:-3].replace('.', '/').strip()


def polybuild_face_at_cursor_move(MESH_OT_polybuild_face_at_cursor=None,
    TRANSFORM_OT_translate=None):
    """Undocumented contribute <https://developer.blender.org/T51061>

    :param MESH_OT_polybuild_face_at_cursor: Poly Build Face at Cursor
    :param TRANSFORM_OT_translate: Move, Move selected items
    """
    pass


def is_somatic(var):
    """
    Return whether the variant is somatically acquired
    """
    return var.INFO.get('SOMATIC')


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 get_lin_score(hpo_graph, proband_1, proband_2):
    """ Calculate the similarity in HPO terms between terms for two probands.

    This runs through the pairs of HPO terms from the two probands and finds
    Lin's measure of semantic similarity for each pair. We return the most
    informative score, i.e. the largest.

    Reference:
        Lin, Proc 15th Int'l Conf. on Machine Learning (ICML-98) (1998), 296-304.

    Args:
        hpo_graph: ICSimilarity object for the HPO term graph, with
            information on how many times each term has been used across all
            probands.
        proband_1: list of HPO terms for one proband
        proband_2: list of HPO terms for the other proband

    Returns:
        A score for how similar the terms are between the two probands.
    """
    ic = []
    for term_1 in proband_1:
        for term_2 in proband_2:
            a = 2 * hpo_graph.get_most_informative_ic(term_1, term_2)
            b = hpo_graph.calculate_information_content(term_1)
            c = hpo_graph.calculate_information_content(term_2)
            try:
                ic.append(a / (b + c))
            except ZeroDivisionError:
                ic.append(0)
    return max(ic)


def wavelength_to_colour(lam):
    """Convert a wavelength to a RGB colour

    Will return the color associated to a particular wavelength.

    Args:
        lam (float): The wavelength lambda.

    Returns:
        A tuple (R,G,B) of colors in the 0 to 1 range.

    """
    if lam >= 380 and lam < 440:
        R = -(lam - 440.0) / (440.0 - 350.0)
        G = 0.0
        B = 1.0
    elif lam >= 440 and lam < 490:
        R = 0.0
        G = (lam - 440.0) / (490.0 - 440.0)
        B = 1.0
    elif lam >= 490 and lam < 510:
        R = 0.0
        G = 1.0
        B = -(lam - 510.0) / (510.0 - 490.0)
    elif lam >= 510 and lam < 580:
        R = (lam - 510.0) / (580.0 - 510.0)
        G = 1.0
        B = 0.0
    elif lam >= 580 and lam < 645:
        R = 1.0
        G = -(lam - 645.0) / (645.0 - 580.0)
        B = 0.0
    elif lam >= 645 and lam <= 780:
        R = 1.0
        G = 0.0
        B = 0.0
    else:
        R = 0.0
        G = 0.0
        B = 0.0
    if lam >= 380 and lam < 420:
        SSS = 0.3 + 0.7 * (lam - 350) / (420 - 350)
    elif lam >= 420 and lam <= 700:
        SSS = 1.0
    elif lam > 700 and lam <= 780:
        SSS = 0.3 + 0.7 * (780 - lam) / (780 - 700)
    else:
        SSS = 0.0
    return SSS * R, SSS * G, SSS * B


def compact(text, *args, **kw):
    """
    Compact whitespace in a string.

    Trims leading and trailing whitespace, replaces runs of whitespace
    characters with a single space and interpolates any arguments using
    :func:`format()`.

    :param text: The text to compact (a string).
    :param args: Any positional arguments are interpolated using :func:`format()`.
    :param kw: Any keyword arguments are interpolated using :func:`format()`.
    :returns: The compacted text (a string).

    Here's an example of how I like to use the :func:`compact()` function, this
    is an example from a random unrelated project I'm working on at the moment::

        raise PortDiscoveryError(compact(""\"
            Failed to discover port(s) that Apache is listening on!
            Maybe I'm parsing the wrong configuration file? ({filename})
        ""\", filename=self.ports_config))

    The combination of :func:`compact()` and Python's multi line strings allows
    me to write long text fragments with interpolated variables that are easy
    to write, easy to read and work well with Python's whitespace
    sensitivity.
    """
    non_whitespace_tokens = text.split()
    compacted_text = ' '.join(non_whitespace_tokens)
    return format(compacted_text, *args, **kw)


def is_mutating(status):
    """Determines if the statement is mutating based on the status."""
    if not status:
        return False
    mutating = set(['insert', 'update', 'delete', 'alter', 'create', 'drop',
        'replace', 'truncate', 'load'])
    return status.split(None, 1)[0].lower() in mutating


def constant(_):
    """
    Returns a constant value for the Scheduler

    :param _: ignored
    :return: (float) 1
    """
    return 1.0


def get_linear_fits(method='cifelli'):
    """
    Get coefficients from linear fits to Zdp and Zh
    method = str, Reference for method
        'cifelli': Cifelli et al. (2002) - Amazon
        'cr1995': Carey and Rutledge (1995) - Colorado
        Default: Carey and Rutledge (2000) - Darwin
    """
    if method == 'cifelli':
        fit_a = 0.8178
        fit_b = 12.5088
    elif method == 'cr1995':
        fit_a = 0.9091
        fit_b = 8.5091
    else:
        fit_a = 0.77
        fit_b = 14.0
    return fit_a, fit_b


def lag_correction_image_filter(*args, **kwargs):
    """Procedural interface for LagCorrectionImageFilter"""
    import itk
    instance = itk.LagCorrectionImageFilter.New(*args, **kwargs)
    return instance.__internal_call__()


def compute_edge_weight(hist_one, hist_two, weight_func):
    """
    Computes the edge weight between the two histograms.

    Parameters
    ----------
    hist_one : sequence
        First histogram

    hist_two : sequence
        Second histogram

    weight_func : callable
        Identifying the type of distance (or metric) to compute between the pair of histograms.
        Must be one of the metrics implemented in medpy.metric.histogram, or another valid callable.

    Returns
    -------
    edge_value : float
        Distance or metric between the two histograms
    """
    edge_value = weight_func(hist_one, hist_two)
    return edge_value


def check_equal_constant_time(a, b):
    """
    Return ``True`` if string ``a`` is equal to string ``b``.

    If ``a`` and ``b`` are of the same length, this function will take the same
    amount of time to execute, regardless of whether or not a and b are equal.
    """
    if len(a) != len(b):
        return False
    result = 0
    for c1, c2 in zip(a, b):
        result |= ord(c1) ^ ord(c2)
    return result == 0


def strip_jump(next: bool=True, center: bool=True):
    """Move frame to previous edit point

    :param next: Next Strip
    :type next: bool
    :param center: Use strip center
    :type center: bool
    """
    pass


def createEvent(title, start_date):
    """ Creates a calendar event in the given context and data.

        @return: the newly created event
        """


def glMultMatrix(m: 'Buffer'):
    """Multiply the current matrix with the specified matrix

    :param m: Points to 16 consecutive values that are used as the elements of a 4x4 column major matrix.
    :type m: 'Buffer'
    """
    pass


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:

        [
          {
            "proto":             string,
            "recv_q":            integer,
            "send_q":            integer,
            "transport_protocol" string,
            "network_protocol":  string,
            "local_address":     string,
            "local_port":        string,
            "local_port_num":    integer,
            "foreign_address":   string,
            "foreign_port":      string,
            "foreign_port_num":  integer,
            "state":             string,
            "program_name":      string,
            "pid":               integer,
            "user":              string,
            "security_context":  string,
            "refcnt":            integer,
            "flags":             string,
            "type":              string,
            "inode":             integer,
            "path":              string,
            "kind":              string
          }
        ]
    """
    for entry in proc_data:
        int_list = ['recv_q', 'send_q', 'pid', 'refcnt', 'inode']
        for key in int_list:
            if key in entry:
                try:
                    key_int = int(entry[key])
                    entry[key] = key_int
                except ValueError:
                    entry[key] = None
        if 'local_port' in entry:
            try:
                entry['local_port_num'] = int(entry['local_port'])
            except ValueError:
                pass
        if 'foreign_port' in entry:
            try:
                entry['foreign_port_num'] = int(entry['foreign_port'])
            except ValueError:
                pass
    return proc_data


def debug(msg):
    """
    Send a debug message to the console.
    """
    pass


def vertex_color_brightness_contrast(brightness: float=0.0, contrast: float=0.0
    ):
    """Adjust vertex color brightness/contrast

    :param brightness: Brightness
    :type brightness: float
    :param contrast: Contrast
    :type contrast: float
    """
    pass


def neutral_head_length(ref, alt):
    """
    returns index of first non-N(eutral) nucleotide
    :param ref: e.g NNNNA
    :param alt: e.g NNNNG
    :return:
    """
    i = 0
    while i < len(ref) and ref[i] == 'N' and i < len(alt) and alt[i] == 'N':
        i += 1
    return i


@staticmethod
def format_unicode_to_right_format_string(invalid_format_unicode):
    """
        Convert unicode string to right format string
        :param invalid_format_unicode:
        :return:
        """
    return str(invalid_format_unicode.encode('ascii', 'ignore').decode('ascii')
        ).replace('\n', '')


def read_file(filename, mode='rb'):
    """ Read the contents of the file named filename and return it in
    a string. This function closes the file handle before it returns
    (even if the underlying Python implementation's garbage collector
    doesn't). """
    fh = open(filename, mode)
    try:
        return fh.read()
    finally:
        fh.close()


def isrtl(doc):
    """Checks if the document should be rendered in right-to-left fashion"""
    if doc.metadata:
        if doc.metadatatype == 'native':
            if 'direction' in doc.metadata and doc.metadata['direction'
                ] == 'rtl':
                return True
        lang = doc.language()
        if lang:
            return lang.lower() in ('ar', 'fa', 'ur', 'ps', 'sd', 'he',
                'yi', 'dv', 'ug', 'ara', 'fas', 'urd', 'pus', 'snd', 'heb',
                'yid', 'arc', 'syc', 'syr', 'div', 'uig', 'arz', 'ary',
                'auz', 'ayl', 'acm', 'acw', 'acx', 'aec', 'afb', 'ajp',
                'apd', 'arb', 'arq', 'arabic', 'hebrew', 'urdu', 'persian',
                'farsi')
    return False


def tr_tet_tet_coord_test(x, y, z):
    """Test for coordinate in tretrahedron/truncated tetrahedron grid"""
    return x % 2 == 0 and y % 4 == (x + z) % 4 or y % 2 == 0 and z % 4 == (y +
        x) % 4 or z % 2 == 0 and x % 4 == (z + y) % 4


def get_numpy_include_path():
    """
    Gets the path to the numpy headers.
    """
    import builtins
    if hasattr(builtins, '__NUMPY_SETUP__'):
        del builtins.__NUMPY_SETUP__
    import imp
    import numpy
    imp.reload(numpy)
    try:
        numpy_include = numpy.get_include()
    except AttributeError:
        numpy_include = numpy.get_numpy_include()
    return numpy_include


def whitespace_tokenize(text):
    """Runs basic whitespace cleaning and splitting on a peice of text."""
    text = text.strip()
    if not text:
        return []
    tokens = text.split()
    return tokens


def select_alternate(unselect_ends: bool=True):
    """Select alternative points in same strokes as already selected points

    :param unselect_ends: Unselect Ends, Do not select the first and last point of the stroke
    :type unselect_ends: bool
    """
    pass


def python_file_run(filepath: str=''):
    """Run Python file

    :param filepath: Path
    :type filepath: str
    """
    pass


def get_flags(args):
    """Returns the options set in the command line string normalized ("_" is
       transformed to "-")

    """
    train_stdin = False
    test_stdin = False
    flags = []
    for i in range(0, len(args)):
        if args[i].startswith('--'):
            flag = args[i]
            value = None
            if '=' in flag:
                value = args[i][flag.index('='):]
                args[i] = args[i][0:flag.index('=')]
            args[i] = args[i].replace('_', '-')
            flag = args[i]
            if value:
                args[i] = '%s%s' % (flag, value)
            flags.append(flag)
            if flag == '--train' and (i == len(args) - 1 or args[i + 1].
                startswith('--')):
                train_stdin = True
            elif flag == '--test' and (i == len(args) - 1 or args[i + 1].
                startswith('--')):
                test_stdin = True
    return flags, train_stdin, test_stdin


def añadir_exp(símismo, experimento, corresp):
    """
        Esta función añade un experimento al Simulable.

        :param experimento: El experimento para añadir
        :type experimento: Experimento

        :param corresp: Un diccionario con la información necesaria para hacer la conexión entre el experimento
        y las predicciones del Simulable.
        :type corresp: dict

        """
    if not símismo.listo:
        símismo.actualizar()
    símismo.exps[experimento.nombre] = {'Exp': experimento, 'Corresp': corresp}
    símismo._actualizar_vínculos_exps()


@classmethod
def supports_to_pcm(cls):
    """returns True if all necessary components are available
        to support the .to_pcm() method"""
    try:
        from audiotools.decoders import ALACDecoder
        return True
    except ImportError:
        return False


def _role_matches(client, role, role_document, policy_arn):
    """Does the given role data structure have the given policy document
    and the given policy ARN attached?

    (Roles can have up to two policy ARNs attached, but we don't need this
    functionality.)
    """
    if role['AssumeRolePolicyDocument'] != role_document:
        return False
    policy_resp = client.list_attached_role_policies(RoleName=role['RoleName'])
    policies = policy_resp['AttachedPolicies']
    return len(policies) == 1 and policies[0]['PolicyArn'] == policy_arn


def scaledUnitString(num, infix=' ', suffix='B', div=1000):
    """
    Returns a human-readable file size string.
    thanks to Fred Cirera
    http://stackoverflow.com/questions/1094841/reusable-library-to-get-human-readable-version-of-file-size
    :param num: number in bytes
    :param suffix: 'B' for bytes by default.
    :param div: divisor of num, 1000 by default.
    :return: the file size string
    """
    for unit in ['', 'K', 'M', 'G', 'T', 'P', 'E', 'Z']:
        if abs(num) < div:
            return '{:3.1f}{}{}{}'.format(num, infix, unit, suffix)
        num /= div
    return '{:.1f}{}{}{}'.format(num, infix, unit, suffix)


@classmethod
def from_getsockname(cls, sock):
    """Creates a :class:`PtrLookup` object based on the IP address of the
        socket's local address, using :py:meth:`~socket.socket.getsockname`.

        :param sock: The :py:class:`~socket.socket` object to use.
        :returns: A tuple containing the new :class:`PtrLookup` object and the
                  port number from :py:meth:`~socket.socket.getsockname`.

        """
    ip, port = sock.getsockname()
    return cls(ip), port


@staticmethod
def _readMeta(fd):
    """Read meta array from the top of a file. Read lines until a blank line is reached.
        This function should ideally work for ALL versions of MetaArray.
        """
    meta = ''
    while True:
        line = fd.readline().strip()
        if line == '':
            break
        meta += line
    ret = eval(meta)
    return ret


def check_between(v_min, v_max, **params):
    """Checks parameters are in a specified range

    Parameters
    ----------

    v_min : float, minimum allowed value (inclusive)

    v_max : float, maximum allowed value (inclusive)

    params : object
        Named arguments, parameters to be checked

    Raises
    ------
    ValueError : unacceptable choice of parameters
    """
    for p in params:
        if params[p] < v_min or params[p] > v_max:
            raise ValueError('Expected {} between {} and {}, got {}'.format
                (p, v_min, v_max, params[p]))


@classmethod
def apply_suggester_completion(cls, suggester_name, queryset, options, value):
    """Apply `completion` suggester.

        :param suggester_name:
        :param queryset: Original queryset.
        :param options: Filter options.
        :param value: value to filter on.
        :type suggester_name: str
        :type queryset: elasticsearch_dsl.search.Search
        :type options: dict
        :type value: str
        :return: Modified queryset.
        :rtype: elasticsearch_dsl.search.Search
        """
    completion_kwargs = {'field': options['field']}
    if 'size' in options:
        completion_kwargs['size'] = options['size']
    if 'contexts' in options:
        completion_kwargs['contexts'] = options['contexts']
    if 'skip_duplicates' in options:
        completion_kwargs['skip_duplicates'] = options['skip_duplicates']
    return queryset.suggest(suggester_name, value, completion=completion_kwargs
        )


@staticmethod
def runtimeConverter(runtime):
    """
        Static method that converts a float amount of seconds into seconds,
        minutes, hours, days.

        Parameters
        ----------
        runtime : float (seconds)

        Returns
        -------
        tuple
            tuple of ([secs],[mins],[hours],[days])
        """
    seconds = runtime % 60
    mins_tot = runtime / 60
    minutes = int(mins_tot % 60)
    hours_tot = mins_tot / 60
    hours = int(hours_tot % 24)
    days_tot = hours_tot / 24
    days = int(days_tot)
    return seconds, minutes, hours, days


def get_i18n_strings(_):
    """Return translations for i18n strings"""
    return {'i18n_art_tags': _('Articles with tag: %s'), 'i18n_tags': _(
        'Tags'), 'i18n_about': _('About me'), 'i18n_archives': _('Archives'
        ), 'i18n_main': _('Blog'), 'i18n_rss_feed': _('RSS feed'),
        'i18n_noscript': _(
        'Please, enable JavaScript in order to use searching feature.'),
        'i18n_search': _('Search'), 'i18n_search_placeholder': _('Search…'),
        'i18n_search_results_ttile': _('Search results'),
        'i18n_search_progress': _('Search in progress. Please wait.'),
        'i18n_search_results': _('Results for phrase "{sp}"'),
        'i18n_search_not_found': _('No results for phrase "{sp}"'),
        'i18n_subscribe': _('Subscribe'), 'i18n_subscribe_desc': _(
        'Subscribe via RSS')}


def local_uuid():
    """create home made uuid"""
    global LOCAL_UUID
    LOCAL_UUID = LOCAL_UUID + 1
    return LOCAL_UUID


def convert_to_anchor(reference: str) ->str:
    """
    Convert reference string into correct anchor

    >>> convert_to_anchor('GET /endpoint/method{id}')
    'get-endpoint-method-id'
    """
    result = ''
    accum = False
    header = reference
    for char in header:
        if char == '_' or char.isalpha():
            if accum:
                accum = False
                result += f'-{char.lower()}'
            else:
                result += char.lower()
        else:
            accum = True
    return result.strip(' -')


def smart_project(angle_limit: float=66.0, island_margin: float=0.0,
    user_area_weight: float=0.0, use_aspect: bool=True, stretch_to_bounds:
    bool=True):
    """This script projection unwraps the selected faces of a mesh (it operates on all selected mesh objects, and can be used to unwrap selected faces, or all faces)

    :param angle_limit: Angle Limit, Lower for more projection groups, higher for less distortion
    :type angle_limit: float
    :param island_margin: Island Margin, Margin to reduce bleed from adjacent islands
    :type island_margin: float
    :param user_area_weight: Area Weight, Weight projections vector by faces with larger areas
    :type user_area_weight: float
    :param use_aspect: Correct Aspect, Map UVs taking image aspect ratio into account
    :type use_aspect: bool
    :param stretch_to_bounds: Stretch to UV Bounds, Stretch the final output to texture bounds
    :type stretch_to_bounds: bool
    """
    pass


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

        :param FileMetadata val:
        :rtype: SaveUrlResult
        """
    return cls('complete', val)


def human_readable(n, digits=3):
    """
    return a human readable number of bytes.

    args:
        * n (float): the number to return as human readable.
        * digits (int): the number of digits before the decimal point.

    returns:
        tuple:
            0. (float) human readable number or None if n is None.
            #. (str) suffix or None if n is None.
    """
    suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
    suffix = suffixes[0]
    for c in suffixes[1:]:
        if len(str(abs(int(n)))) > digits:
            n /= 1024
            suffix = c
    return n, suffix


@classmethod
def normalize_email(cls, email):
    """
        Normalize the address by lowercasing the domain part of the email
        address.
        """
    email = email or ''
    try:
        email_name, domain_part = email.strip().rsplit('@', 1)
    except ValueError:
        pass
    else:
        email = '@'.join([email_name, domain_part.lower()])
    return email


def between(arr, lowval, highval, type='[)'):
    """
    test values of an array are between the specified values

    parameters
    ----------
    arr: array
        numpy array
    lowval: scalar
        lower value
    highval: scalar
        high value
    type: string, optional
        Interval type, one of [] () [) (]

        default [) mimicking slices for integers.  The distinction is often
        less meaningful for floating points

    returns
    -------
    bool array with True for values in the range and False otherwise

    example
    -------

    # select elements that equal 3 or are between 10 and 100 with slice
    # symantics [), e.g. [10,100)

    a=numpy.arange(200)
    w,=numpy.where( (a==3) | between(a,10,100) )

    # select elements that equal 3 or are between 10 and 100, inclusive, e.g.
    # [10,100]

    a=numpy.arange(200)
    w,=numpy.where( (a==3) | between(a,10,100,'[]') )
    """
    if type == '[)':
        logic = (arr >= lowval) & (arr < highval)
    elif type == '[]':
        logic = (arr >= lowval) & (arr <= highval)
    elif type == '()':
        logic = (arr > lowval) & (arr < highval)
    elif type == '(]':
        logic = (arr > lowval) & (arr <= highval)
    else:
        raise ValueError("bad range type: '%s'" % type)
    return logic


def _get_min_overlap_timestamp(df1_timestamps, df2_timestamps):
    """
    Get the minimum overlapping timestamp from two series
    """
    if df1_timestamps.max() < df2_timestamps.min() or df1_timestamps.min(
        ) > df2_timestamps.max():
        raise IndexError(
            'No overlapping data. Ranges: {0} to {1}  and {2} to {3}'.
            format(df1_timestamps.min(), df1_timestamps.max(),
            df2_timestamps.min(), df2_timestamps.max()))
    return max(df1_timestamps.min(), df2_timestamps.min())


@staticmethod
def get_batch_axis(layout):
    """Get the dimension that corresponds to the batch size.

        When data parallelism is used, the data will be automatically split and
        concatenated along the batch-size dimension. Axis can be -1, which means
        the whole array will be copied for each data-parallelism device.

        Parameters
        ----------
        layout : str
            layout string. For example, "NCHW".

        Returns
        -------
        int
            An axis indicating the batch_size dimension.
        """
    if layout is None:
        return 0
    return layout.find('N')


def p_static_heredoc(p):
    """static_heredoc : START_HEREDOC multiple_encapsed END_HEREDOC"""
    p[0] = p[2][:-1]


def dict_from_cookiejar(cj):
    """Returns a key/value dictionary from a CookieJar.

    :param cj: CookieJar object to extract cookies from.
    :rtype: dict
    """
    cookie_dict = {}
    for cookie in cj:
        cookie_dict[cookie.name] = cookie.value
    return cookie_dict


@classmethod
def register_notification_objects(cls):
    """Register previously decorated notification as normal ovos.

        This is not intended for production use but only for testing and
        document generation purposes.
        """
    for notification_cls in cls.notification_classes:
        cls.register(notification_cls)


def equal():
    """
    Generate a check function that checks whether two values are equivalent
    using Python's `==`.

    **Parameters:** none

    **Returns:** a function suitable for use as a `csq_check_function`.
    """
    return lambda sub, soln: sub == soln


def vega(flag, S, K, t, r, sigma, b, pricing_function):
    """Calculate option vega using numerical integration.

    :param S: underlying asset price
    :type S: float
    :param K: strike price
    :type K: float
    :param sigma: annualized standard deviation, or volatility
    :type sigma: float
    :param t: time to expiration in years
    :type t: float
    :param r: risk-free interest rate
    :type r: float
    :param b: see above
    :type b: float
    :param flag: 'c' or 'p' for call or put.
    :type flag: str
    :param pricing_function: any function returning the price of an option
    :type pricing_function: python function object
    """
    return (pricing_function(flag, S, K, t, r, sigma + 0.01, b) -
        pricing_function(flag, S, K, t, r, sigma - 0.01, b)) / 2.0


@classmethod
def from_index(cls, index):
    """Return the Enum value at a given index."""
    return cls.ALL[index]


def split_haiku(haiku):
    """Split haiku, remove the period and new_line"""
    word_array = haiku.lower().replace('.', '').split()
    return word_array


def _config_to_loggerConf(config):
    """
    Translates a user-provided config to ~`astropy.logger.LoggerConf`.
    """
    if config.has_section('logger'):
        from astropy.logger import Conf as LoggerConf
        conf = LoggerConf()
        loggerconf_option_list = ['log_level', 'use_color', 'log_warnings',
            'log_exceptions', 'log_to_file', 'log_file_path',
            'log_file_level', 'log_file_format']
        for this_option in loggerconf_option_list:
            if config.has_option('logger', this_option):
                setattr(conf, this_option, config.get('logger', this_option))
    return conf


def joinitems(itemiter, sep):
    """Join items with the separator; Returns generator of bytes"""
    first = True
    for x in itemiter:
        if first:
            first = False
        elif sep:
            yield sep
        yield x


def analyze_result(typ, indicators, indicator_filter):
    """Check response from API"""
    no_of_indicators = len(indicators[typ])
    if no_of_indicators == 0:
        if indicator_filter:
            msg = 'check your filter.'
        else:
            msg = 'are there any?'
        raise SystemExit('No {} found - {}'.format(typ, msg))
    elif indicator_filter:
        msg = 'Found {} {} with filter {}'.format(no_of_indicators, typ,
            indicator_filter)
    else:
        msg = 'Found {} {}'.format(no_of_indicators, typ)
    return msg


def current_user_name(anonymous_user_name: str='') ->str:
    """
    Provide the name of the current user performing a request (if any).
    :param anonymous_user_name: Default value in case there is no known user performing a request.
    """
    try:
        import flask
        if flask.has_request_context() and hasattr(flask.g, 'current_user'):
            return flask.g.current_user.name
        return anonymous_user_name
    except ImportError:
        return anonymous_user_name


def get_progress_key(request):
    """
    Gets progress/operation key under which operation progress will be stored in servers cache.
    :param request:
    :return: Progress key or None if there is no x_df_timestamp in request header
    """
    timestamp = request.META.get('HTTP_X_DF_TIMESTAMP', request.GET.get(
        'x_df_timestamp', None))
    if timestamp is not None:
        return '%s|%s' % (timestamp, request.session.session_key)
    return None


def reduce_base(amount, base):
    """
    Compute the reduced base of the given parameters
    :param int amount: the amount value
    :param int base: current base value
    :return: tuple containing computed (amount, base)
    :rtype: tuple
    """
    if amount == 0:
        return 0, 0
    next_amount = amount
    next_base = base
    while int(next_amount) == next_amount:
        amount = next_amount
        base = next_base
        next_amount /= 10
        next_base += 1
    return int(amount), int(base)


@classmethod
def unregister_prober(klass, prober):
    """Unregister a prober.

        """
    klass._probers.remove(prober)


def get_remaining_corrupt_shares():
    """Return a set of (IServer, storage_index, sharenum) for all shares
        that were found to be corrupt after any repair was completed.
        storage_index is binary. These are shares that need manual inspection
        and probably deletion.
        """


def is_int(value):
    """
    Returns True if argument is of integer type, otherwise False
    """
    return isinstance(value, int)


def button_top_pressed(controller):
    """
    Callback function that is triggered, when the top button was pressed

    :param controller:              the controller that triggered the action
    :type controller:               steuer.Controller
    """
    print('ACTION:' + str(controller.number) + ':' + controller.name +
        ':Button Top pressed')


def list_distributions_by_web_acl_id(Marker=None, MaxItems=None, WebACLId=None
    ):
    """
    List the distributions that are associated with a specified AWS WAF web ACL.
    See also: AWS API Documentation

    :example: response = client.list_distributions_by_web_acl_id(
        Marker='string',
        MaxItems='string',
        WebACLId='string'
    )

    :type Marker: string
    :param Marker: Use Marker and MaxItems to control pagination of results. If you have more than MaxItems distributions that satisfy the request, the response includes a NextMarker element. To get the next page of results, submit another request. For the value of Marker , specify the value of NextMarker from the last response. (For the first request, omit Marker .)

    :type MaxItems: string
    :param MaxItems: The maximum number of distributions that you want CloudFront to return in the response body. The maximum and default values are both 100.

    :type WebACLId: string
    :param WebACLId: [REQUIRED]
            The ID of the AWS WAF web ACL that you want to list the associated distributions. If you specify 'null' for the ID, the request returns a list of the distributions that aren't associated with a web ACL.

    :rtype: dict
    :return: {
        'DistributionList': {
            'Marker': 'string',
            'NextMarker': 'string',
            'MaxItems': 123,
            'IsTruncated': True|False,
            'Quantity': 123,
            'Items': [
                {
                    'Id': 'string',
                    'ARN': 'string',
                    'Status': 'string',
                    'LastModifiedTime': datetime(2015, 1, 1),
                    'DomainName': 'string',
                    'Aliases': {
                        'Quantity': 123,
                        'Items': [
                            'string',
                        ]
                    },
                    'Origins': {
                        'Quantity': 123,
                        'Items': [
                            {
                                'Id': 'string',
                                'DomainName': 'string',
                                'OriginPath': 'string',
                                'CustomHeaders': {
                                    'Quantity': 123,
                                    'Items': [
                                        {
                                            'HeaderName': 'string',
                                            'HeaderValue': 'string'
                                        },
                                    ]
                                },
                                'S3OriginConfig': {
                                    'OriginAccessIdentity': 'string'
                                },
                                'CustomOriginConfig': {
                                    'HTTPPort': 123,
                                    'HTTPSPort': 123,
                                    'OriginProtocolPolicy': 'http-only'|'match-viewer'|'https-only',
                                    'OriginSslProtocols': {
                                        'Quantity': 123,
                                        'Items': [
                                            'SSLv3'|'TLSv1'|'TLSv1.1'|'TLSv1.2',
                                        ]
                                    },
                                    'OriginReadTimeout': 123,
                                    'OriginKeepaliveTimeout': 123
                                }
                            },
                        ]
                    },
                    'DefaultCacheBehavior': {
                        'TargetOriginId': 'string',
                        'ForwardedValues': {
                            'QueryString': True|False,
                            'Cookies': {
                                'Forward': 'none'|'whitelist'|'all',
                                'WhitelistedNames': {
                                    'Quantity': 123,
                                    'Items': [
                                        'string',
                                    ]
                                }
                            },
                            'Headers': {
                                'Quantity': 123,
                                'Items': [
                                    'string',
                                ]
                            },
                            'QueryStringCacheKeys': {
                                'Quantity': 123,
                                'Items': [
                                    'string',
                                ]
                            }
                        },
                        'TrustedSigners': {
                            'Enabled': True|False,
                            'Quantity': 123,
                            'Items': [
                                'string',
                            ]
                        },
                        'ViewerProtocolPolicy': 'allow-all'|'https-only'|'redirect-to-https',
                        'MinTTL': 123,
                        'AllowedMethods': {
                            'Quantity': 123,
                            'Items': [
                                'GET'|'HEAD'|'POST'|'PUT'|'PATCH'|'OPTIONS'|'DELETE',
                            ],
                            'CachedMethods': {
                                'Quantity': 123,
                                'Items': [
                                    'GET'|'HEAD'|'POST'|'PUT'|'PATCH'|'OPTIONS'|'DELETE',
                                ]
                            }
                        },
                        'SmoothStreaming': True|False,
                        'DefaultTTL': 123,
                        'MaxTTL': 123,
                        'Compress': True|False,
                        'LambdaFunctionAssociations': {
                            'Quantity': 123,
                            'Items': [
                                {
                                    'LambdaFunctionARN': 'string',
                                    'EventType': 'viewer-request'|'viewer-response'|'origin-request'|'origin-response'
                                },
                            ]
                        }
                    },
                    'CacheBehaviors': {
                        'Quantity': 123,
                        'Items': [
                            {
                                'PathPattern': 'string',
                                'TargetOriginId': 'string',
                                'ForwardedValues': {
                                    'QueryString': True|False,
                                    'Cookies': {
                                        'Forward': 'none'|'whitelist'|'all',
                                        'WhitelistedNames': {
                                            'Quantity': 123,
                                            'Items': [
                                                'string',
                                            ]
                                        }
                                    },
                                    'Headers': {
                                        'Quantity': 123,
                                        'Items': [
                                            'string',
                                        ]
                                    },
                                    'QueryStringCacheKeys': {
                                        'Quantity': 123,
                                        'Items': [
                                            'string',
                                        ]
                                    }
                                },
                                'TrustedSigners': {
                                    'Enabled': True|False,
                                    'Quantity': 123,
                                    'Items': [
                                        'string',
                                    ]
                                },
                                'ViewerProtocolPolicy': 'allow-all'|'https-only'|'redirect-to-https',
                                'MinTTL': 123,
                                'AllowedMethods': {
                                    'Quantity': 123,
                                    'Items': [
                                        'GET'|'HEAD'|'POST'|'PUT'|'PATCH'|'OPTIONS'|'DELETE',
                                    ],
                                    'CachedMethods': {
                                        'Quantity': 123,
                                        'Items': [
                                            'GET'|'HEAD'|'POST'|'PUT'|'PATCH'|'OPTIONS'|'DELETE',
                                        ]
                                    }
                                },
                                'SmoothStreaming': True|False,
                                'DefaultTTL': 123,
                                'MaxTTL': 123,
                                'Compress': True|False,
                                'LambdaFunctionAssociations': {
                                    'Quantity': 123,
                                    'Items': [
                                        {
                                            'LambdaFunctionARN': 'string',
                                            'EventType': 'viewer-request'|'viewer-response'|'origin-request'|'origin-response'
                                        },
                                    ]
                                }
                            },
                        ]
                    },
                    'CustomErrorResponses': {
                        'Quantity': 123,
                        'Items': [
                            {
                                'ErrorCode': 123,
                                'ResponsePagePath': 'string',
                                'ResponseCode': 'string',
                                'ErrorCachingMinTTL': 123
                            },
                        ]
                    },
                    'Comment': 'string',
                    'PriceClass': 'PriceClass_100'|'PriceClass_200'|'PriceClass_All',
                    'Enabled': True|False,
                    'ViewerCertificate': {
                        'CloudFrontDefaultCertificate': True|False,
                        'IAMCertificateId': 'string',
                        'ACMCertificateArn': 'string',
                        'SSLSupportMethod': 'sni-only'|'vip',
                        'MinimumProtocolVersion': 'SSLv3'|'TLSv1',
                        'Certificate': 'string',
                        'CertificateSource': 'cloudfront'|'iam'|'acm'
                    },
                    'Restrictions': {
                        'GeoRestriction': {
                            'RestrictionType': 'blacklist'|'whitelist'|'none',
                            'Quantity': 123,
                            'Items': [
                                'string',
                            ]
                        }
                    },
                    'WebACLId': 'string',
                    'HttpVersion': 'http1.1'|'http2',
                    'IsIPV6Enabled': True|False
                },
            ]
        }
    }

    :returns:
    (string) --

    """
    pass


def iso_name_converter(iso):
    """
    Converts the name of the given isotope (input), e.g., 'N-14' to
    14N as used later to compare w/ grain database.

    """
    sp = iso.split('-')
    output = sp[1] + sp[0]
    return output.lower()


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 setpriority(pid=None, priority=1):
    """ Set The Priority of a Windows Process.  Priority is a value between 0-5 where
        2 is normal priority.  Default sets the priority of the current
        python process but can take any valid process ID. """
    import win32api, win32process, win32con
    priorityclasses = [win32process.IDLE_PRIORITY_CLASS, win32process.
        BELOW_NORMAL_PRIORITY_CLASS, win32process.NORMAL_PRIORITY_CLASS,
        win32process.ABOVE_NORMAL_PRIORITY_CLASS, win32process.
        HIGH_PRIORITY_CLASS, win32process.REALTIME_PRIORITY_CLASS]
    if pid == None:
        pid = win32api.GetCurrentProcessId()
    handle = win32api.OpenProcess(win32con.PROCESS_ALL_ACCESS, True, pid)
    win32process.SetPriorityClass(handle, priorityclasses[priority])


def get_valid_package_id_from_string(package_id_string):
    """Validate and return package ID from string.

    This function assumes that the company's package ID numbers
    will always be less than 1000. This assumption is shared by a
    Package class method (validate_package_ID_list method).
    """
    ID = int(package_id_string.strip())
    if not ID > 0:
        raise ValueError('Package ID found in special note too small')
    if not ID < 1000:
        raise ValueError('Package ID found in special note too large')
    return ID


def clear_schema():
    """Clear global schema."""
    global _schema
    _schema = None


def find_node(prev: bool=False):
    """Search for named node and allow to select and activate it

    :param prev: Previous
    :type prev: bool
    """
    pass


def set_visible(ax, boolean, *args):
    """
    Hide/Show the artists of axis ax listed in args.
    """
    if 'legend' in args and ax.legend():
        ax.legend().set_visible(boolean)
    if 'title' in args and ax.title:
        ax.title.set_visible(boolean)
    if 'xlabel' in args and ax.xaxis.label:
        ax.xaxis.label.set_visible(boolean)
    if 'ylabel' in args and ax.yaxis.label:
        ax.yaxis.label.set_visible(boolean)
    if 'xticklabels' in args:
        for label in ax.get_xticklabels():
            label.set_visible(boolean)
    if 'yticklabels' in args:
        for label in ax.get_yticklabels():
            label.set_visible(boolean)


def get_iterator(num_chunks, verbose):
    """utility function to add a progress bar if verbosity is set to True."""
    if verbose:
        from tqdm import tqdm
        iterator = tqdm(range(num_chunks), desc='building dict')
    else:
        iterator = range(num_chunks)
    return iterator


def strain_from_metric_difference(Ginit, Gfinal):
    """
    does not seem to work ...
    TODO to repair?
    """
    return 0.5 * (Gfinal - Ginit)


def command_retry_count(command):
    """ returns the retry_count kept in the headers
    :param command: the command message whose retries needs to be counted
    :returns the value of the retry_count from the header
    """
    return command.header_frame.headers.get('max_retry', None)


def get_header_hgarg(environ):
    """Decode the special Mercurial encoding of big requests over multiple headers.
    >>> get_header_hgarg({})
    ''
    >>> get_header_hgarg({'HTTP_X_HGARG_0': ' ', 'HTTP_X_HGARG_1': 'a','HTTP_X_HGARG_2': '','HTTP_X_HGARG_3': 'b+c %20'})
    'ab+c %20'
    """
    chunks = []
    i = 1
    while True:
        v = environ.get('HTTP_X_HGARG_%d' % i)
        if v is None:
            break
        chunks.append(v)
        i += 1
    return ''.join(chunks)


@staticmethod
def cache_hit_callback(key):
    """Output when a cache hit occurs."""
    print('HIT {0} {1}'.format('POST' if key[1][1] else 'GET', key[0]))


def constraints_clear():
    """Clear all the constraints for the active Object only

    """
    pass


def _to_int(field):
    """ Transform to int """
    return int(field)


def calculate_onedimensional_distance(x, y, horizontal=True):
    """
    x and y are 2D positions.

    horizontal checks whether we measure horizontal or vertical distance.
    """
    x = list(x)
    y = list(y)
    x[0] = float(x[0])
    x[1] = float(x[1])
    y[0] = float(y[0])
    y[1] = float(y[1])
    if horizontal:
        return abs(x[0] - y[0])
    else:
        return abs(x[1] - y[1])


def unmap_with_copy(indices, src_tokens, vocab):
    """
    Unmap a list of list of indices, by optionally copying from src_tokens.
    """
    result = []
    for ind, tokens in zip(indices, src_tokens):
        words = []
        for idx in ind:
            if idx >= 0:
                words.append(vocab.id2word[idx])
            else:
                idx = -idx - 1
                words.append(tokens[idx])
        result += [words]
    return result


@staticmethod
def _getAncestor(adaptor, tokenNames, t, goal):
    """Helper for static inContext."""
    while t is not None:
        name = tokenNames[adaptor.getType(t)]
        if name == goal:
            return t
        t = adaptor.getParent(t)
    return None


def freestyle_lineset_copy():
    """Copy the active line set to a buffer

    """
    pass


def chunks(l, n):
    """
    Yield successive n-sized chunks from l.
    Reference: https://stackoverflow.com/questions/312443/how-do-you-split-a-list-into-evenly-sized-chunks
    """
    for i in range(0, len(l), n):
        yield l[i:i + n]


def PowerStack_Calc(Power, N):
    """
    Calculate power_stack.

    :param Power: single cell power [W]
    :type Power : float
    :param N: number of single cells
    :type N : int
    :return: power stack [W] as float
    """
    try:
        result = N * Power
        return result
    except TypeError:
        print('[Error] Power Stack Calculation Error (Power:%s, N:%s)' % (
            str(Power), str(N)))


def render_longest_xsection_to_svg(mesh, plane, filename, look=None, **kwargs):
    """
    Rectangle of specified height and width along the plane normal,
    with given up vector, centered on the plane's reference point.

    When width or height is not provided, automatically set based on the data
    with 10% padding.
    """
    from .mesh import longest_xsection
    from .svg import write_polyline_3d
    if look is None:
        look = plane.normal
    xs = longest_xsection(mesh, plane)
    write_polyline_3d(polyline=xs, filename=filename, look=look, **kwargs)
    return xs


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 i2be_padded(number: int, length: int) ->bytes:
    """
    Convert int to big endian (b.e.) bytes with specified length

    Args:
        number: int value to convert to bytes in BE format
        length: length of resulting bytes
    Returns:
        bytes in BE format with specified length
    """
    return number.to_bytes(length, 'big')


def calc_dF_F(Ft, Fo):
    """
    Takes inputs Ft and Fo and returns dF/F
    """
    dF_F = (Ft - Fo) / Fo
    return dF_F


def _null(parent, arg):
    """Return nothing regardless of args or parent."""
    return ''


def dictSort(d):
    """returns a dictionary sorted by keys

    >>> d = {"a": "1", "b": "3", "c": "2"}

    >>> dictSort(d)
    {'a': '1', 'c': '2', 'b': '3'}
    """
    our_list = d.items()
    our_list.sort()
    k = {}
    for item in our_list:
        k[item[0]] = item[1]
    return k


def is_directed(G):
    """ Return True if graph is directed."""
    return G.is_directed()


@classmethod
def open(cls, filename, bestEffort=True, DRUFile=None):
    """
        Loads a Eagle file from a .sch, .lbr, or .brd file.  A synonym for :meth:`EagleFile.from_file`

        :param filename: Filename to load.
        :param bestEffort: If :code:`True`, load the file even if it doesn't conform to the DTD.
        :param DRUFile: A DRU file to use.  You don't need to worry about this unless you need precisely correct answers to questions about the geometry of things on your board.  By default, it uses sensible defaults.
        :returns: A new :class:`BoardFile`, :class:`LibraryFile`, or :class:`SchematicFile` object
        """
    return cls.from_file(filename, bestEffort, DRUFile)


@staticmethod
def remove_duplicates(df):
    """ Sort the dataframe and remove duplicates -- note, not extensively tested """
    p1 = df[['p1', 'p2']].values.min(1)
    p2 = df[['p1', 'p2']].values.max(1)
    df['p1'] = p1
    df['p2'] = p2
    df.sort_values(['p1', 'p2'], inplace=True)
    df.drop_duplicates(['p1', 'p2'], inplace=True)
    df = df[df['p1'] != df['p2']]
    df.reset_index(inplace=True, drop=True)
    return df


def parse_uri(uri):
    """Extracts the host, port and db from an uri"""
    host, port, db = uri, 6379, 0
    if len(host.split('/')) == 2:
        host, db = host.split('/')
    if len(host.split(':')) == 2:
        host, port = host.split(':')
    return host, int(port), int(db)


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

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

    """
    pass


def quadratic_residues(p):
    """Returns the list of quadratic residues.

    Examples
    ========

    >>> quadratic_residues(7)
    [0, 1, 2, 4]

    """
    r = set()
    for i in range(p // 2 + 1):
        r.add(pow(i, 2, p))
    return sorted(r)


def columns_tag_from_columns(columns):
    """Generate a columns tag, to customize phase names based on the number of columns of data extracted in the fit,
    which is used to speed up parallel CTI fits.

    This changes the phase name 'phase_name' as follows:

    columns = None -> phase_name
    columns = 10 -> phase_name_col_10
    columns = 60 -> phase_name_col_60
    """
    if columns == None:
        return ''
    else:
        return '_col_' + str(int(columns))


def nsname(xmlns):
    """
	If ``xmlns`` is a module, return ``xmlns.xmlns``, else return
	``xmlns`` unchanged.
	"""
    if xmlns is not None and not isinstance(xmlns, str):
        xmlns = xmlns.xmlns
    return xmlns


def ln(label):
    """Draw a 70-char-wide divider, with label in the middle.

    >>> ln('hello there')
    '---------------------------- hello there -----------------------------'
    """
    label_len = len(label) + 2
    chunk = (70 - label_len) // 2
    out = '%s %s %s' % ('-' * chunk, label, '-' * chunk)
    pad = 70 - len(out)
    if pad > 0:
        out = out + '-' * pad
    return out


@staticmethod
def addIfValid(sumV, toAdd):
    """
        return the sum of the two given parameters (or None if the case)
        """
    if toAdd is None:
        return sumV
    if sumV is None:
        return toAdd
    return sumV + toAdd


def bwf_info(c):
    """ create the text info related to the box_wood_frame
  """
    r_info = ''
    r_info += (
        """
1. parameter values:
====================
box_width             : {:0.2f}
box_depth             : {:0.2f}
box_height            : {:0.2f}
module_width          : {:d} (in number of box)
fitting_height        : {:0.2f}
h_plank_width         : {:0.2f}
v_plank_width         : {:0.2f}
plank_height          : {:0.2f}
d_plank_width         : {:0.2f}
d_plank_height        : {:0.2f}
crenel_depth          : {:0.2f}
wall_diagonal_size    : {:0.2f}
tobo_diagonal_size    : {:0.2f}
diagonal_lining_top_height    : {:0.2f}
diagonal_lining_bottom_height : {:0.2f}
router_bit_radius         : {:0.2f}
cutting_extra         : {:0.2f}
slab_thickness        : {:0.2f}
"""
        .format(c['box_width'], c['box_depth'], c['box_height'], c[
        'module_width'], c['fitting_height'], c['h_plank_width'], c[
        'v_plank_width'], c['plank_height'], c['d_plank_width'], c[
        'd_plank_height'], c['crenel_depth'], c['wall_diagonal_size'], c[
        'tobo_diagonal_size'], c['diagonal_lining_top_height'], c[
        'diagonal_lining_bottom_height'], c['router_bit_radius'], c[
        'cutting_extra'], c['slab_thickness']))
    return r_info


def get_supported_lang():
    """Get a list of the model programming languages that are supported
    by yggdrasil.

    Returns:
        list: The names of programming languages supported by yggdrasil.

    """
    from yggdrasil import schema
    s = schema.get_schema()
    out = s['model'].subtypes
    if 'c++' in out:
        out[out.index('c++')] = 'cpp'
    if 'r' in out:
        out[out.index('r')] = 'R'
    return list(set(out))


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

        :param TeamMergeRequestExpiredShownToSecondaryTeamType val:
        :rtype: EventType
        """
    return cls('team_merge_request_expired_shown_to_secondary_team', val)


def timestamp_from_datetime(datetime):
    """
        Convert from datetime format to timestamp format
        Input: Time in datetime format
        Output: Time in timestamp format
    """
    return datetime.strftime('%Y-%m-%dT%H:%M:%S.%fZ')


def dummy_pack(k, v):
    """Dummy pack func for shared_func in process_kv."""
    return k, v


def qmake_quote(path):
    """ Return a path quoted for qmake if it contains spaces.  path is the
    path.
    """
    if ' ' in path:
        path = '$$quote(%s)' % path
    return path


def _update_from_arg(cfg, argdict, key):
    """Helper function for get_cfg."""
    for var in cfg[key]:
        if var in argdict and argdict[var] is not None:
            cfg[key][var] = argdict[var]