@classmethod
def _parse_value(cls, stream_rdr, offset, value_count, value_offset):
    """
        Return the long int value contained in the *value_offset* field of
        this entry. Only supports single values at present.
        """
    if value_count == 1:
        return stream_rdr.read_long(offset, 8)
    else:
        return 'Multi-value long integer NOT IMPLEMENTED'


def check_existing_by_datasetid(syn, datasetids, file_view_id):
    """Check a file view that has a 'datasetid' column to see which datasetids exist.

    """
    res = syn.tableQuery('select id,datasetid from %s' % (file_view_id,))
    d = res.asDataFrame()
    existing_datasetids = set(d.datasetid.tolist())
    given_datasetids = set(datasetids)
    return {'exists': given_datasetids.intersection(existing_datasetids),
        'not_exists': given_datasetids.difference(existing_datasetids)}


def _merge_foreign_keys(fk_constraints, fk_relations):
    """
    Merge annotated foreign key relations into foreign key constraints.

    (Both constraints and relations are for the same table.)
    Add all relations, except if a matching constraint exists: then amend
    the constraint by adding cardinality information.
    """
    for rel in fk_relations:
        for constr in fk_constraints:
            if rel['fields'] == constr['fields']:
                r1 = rel['reference']
                r2 = constr['reference']
                if r1['datapackage'] == r2['datapackage'] and r1['resource'
                    ] == r2['resource'] and r1['fields'] == r2['fields']:
                    r2['cardinalitySelf'] = r1['cardinalitySelf']
                    r2['cardinalityRef'] = r1['cardinalityRef']
                    break
        else:
            fk_constraints.append(rel)


def close(z):
    """
    Close *z* if possible.
    """
    if hasattr(z, 'close'):
        z.close()


def overplot_ds9reg(filename, ax):
    """Overplot a ds9 region file.

    Parameters
    ----------
    filename : str
        File name of the ds9 region file.
    ax : matplotlib axes instance
        Matplotlib axes instance.

    """
    with open(filename) as f:
        file_content = f.read().splitlines()
    first_line = file_content[0]
    if '# Region file format: DS9' not in first_line:
        raise ValueError('Unrecognized ds9 region file format')
    for line in file_content:
        if line[0:4] == 'line':
            line_fields = line.split()
            x1 = float(line_fields[1])
            y1 = float(line_fields[2])
            x2 = float(line_fields[3])
            y2 = float(line_fields[4])
            if 'color' in line:
                i = line.find('color=')
                color = line[i + 6:i + 13]
            else:
                color = 'green'
            ax.plot([x1, x2], [y1, y2], '-', color=color)
        elif line[0:4] == 'text':
            line_fields = line.split()
            x0 = float(line_fields[1])
            y0 = float(line_fields[2])
            text = line_fields[3][1:-1]
            if 'color' in line:
                i = line.find('color=')
                color = line[i + 6:i + 13]
            else:
                color = 'green'
            ax.text(x0, y0, text, fontsize=8, bbox=dict(boxstyle=
                'round,pad=0.1', fc='white', ec='grey'), color=color,
                fontweight='bold', backgroundcolor='white', ha='center')
        else:
            pass


def gather_row(data, row_index):
    """Slice out the data given the row index.

    Parameters
    ----------
    data : Tensor
        The data tensor
    row_index : Tensor
        A 1-D integer tensor containing which rows to be sliced out.

    Returns
    -------
    Tensor
        The sliced data. The first dimension should equal to ``len(row_index)``.
    """
    pass


def get_barcode2bcr1r2(dbarcodes, bc2seq, oligo2seq):
    """
    row for:   RC_for_index
    col rev:   RC_rev_index
    plate for: PE1_index
    plate rev: PE2_index
    """
    import re
    dbarcodes.index = range(len(dbarcodes))
    barcode2bcr1r2 = {}
    barcode2primersr1r2 = {}
    barcode2fragsr1r2 = {}
    barcode2regsr1r2 = {}
    for i in dbarcodes.drop_duplicates(subset=['barcode']).index:
        x = dbarcodes.iloc[(i), :]
        barcode = x['barcode']
        barcode2bcr1r2[barcode] = (
            f"{bc2seq[str(x['plate for'])]}{bc2seq[str(x['row for'])]}{bc2seq[str(x['plate rev'])]}{bc2seq[str(x['col rev'])]}"
            )
        barcode2primersr1r2[barcode] = [
            f"{bc2seq[str(x['plate for'])]}{oligo2seq['plate_fivep_sticky']}{bc2seq[str(x['row for'])]}{oligo2seq['RC_fivep_sticky']}"
            ,
            f"{bc2seq[str(x['plate rev'])]}{oligo2seq['plate_threep_sticky']}{bc2seq[str(x['col rev'])]}{oligo2seq['RC_threep_sticky']}"
            ]
        barcode2fragsr1r2[barcode] = [
            f"<{bc2seq[str(x['plate for'])]}><{oligo2seq['plate_fivep_sticky']}><{bc2seq[str(x['row for'])]}><{oligo2seq['RC_fivep_sticky']}"
            ,
            f"<{bc2seq[str(x['plate rev'])]}><{oligo2seq['plate_threep_sticky']}><{bc2seq[str(x['col rev'])]}><{oligo2seq['RC_threep_sticky']}"
            ]
        reg_r1 = re.compile('^\\w{5}' + f'{barcode2primersr1r2[barcode][0]}.*')
        reg_r2 = re.compile('^\\w{5}' + f'{barcode2primersr1r2[barcode][1]}.*')
        barcode2regsr1r2[barcode] = [reg_r1, reg_r2]
    linkerr1r2 = (
        f"{oligo2seq['plate_fivep_sticky']}{oligo2seq['RC_fivep_sticky']}{oligo2seq['plate_threep_sticky']}{oligo2seq['RC_threep_sticky']}"
        )
    barcode2bcr1r2 = {'barcode2bcr1r2': barcode2bcr1r2,
        'barcode2primersr1r2': barcode2primersr1r2, 'barcode2fragsr1r2':
        barcode2fragsr1r2, 'barcode2regsr1r2': barcode2regsr1r2,
        'linkerr1r2': linkerr1r2}
    for k in barcode2bcr1r2:
        if k.startswith('barcode2'):
            dbarcodes[k.replace('barcode2', '')] = dbarcodes['barcode'].map(
                barcode2bcr1r2[k])
    return barcode2bcr1r2


def split_hash(hashed):
    """Split the hashed password into it's components.

    Returns a tuple with the hash name, cost and salt.

        >>> split_hash('dsha512$13$mysalt$myhash')
        ('dsha512', 13, 'mysalt')
        >>> split_hash('bcrypt$06$mysaltyhash')
        ('bcrypt', 6, 'mysaltyhash')

    """
    lhashed = hashed.split('$')
    if len(lhashed) < 3:
        raise ValueError
    return lhashed[0], int(lhashed[1]), lhashed[2]


def find(function, iterable):
    """ Returns the first item in the list for which function(item) is True, None otherwise.
    """
    for x in iterable:
        if function(x) == True:
            return x


def trivial_forecast(submodel, horizon):
    """Computing the forecast for the trivial models

    """
    points = []
    submodel_points = submodel['value']
    period = len(submodel_points)
    if period > 1:
        for h in range(horizon):
            points.append(submodel_points[h % period])
    else:
        for _ in range(horizon):
            points.append(submodel_points[0])
    return points


def removeService(service):
    """
        Remove a service from this collection.
        """


def delete_preset(Id=None):
    """
    The DeletePreset operation removes a preset that you've added in an AWS region.
    See also: AWS API Documentation

    :example: response = client.delete_preset(
        Id='string'
    )

    :type Id: string
    :param Id: [REQUIRED]
            The identifier of the preset for which you want to get detailed information.

    :rtype: dict
    :return: {}

    """
    pass


@classmethod
def _get_sma(cls, df, column, windows):
    """ get simple moving average

        :param df: data
        :param column: column to calculate
        :param windows: collection of window of simple moving average
        :return: None
        """
    window = cls.get_only_one_positive_int(windows)
    column_name = '{}_{}_sma'.format(column, window)
    df[column_name] = df[column].rolling(min_periods=1, window=window,
        center=False).mean()


def select_more():
    """Select control points directly linked to already selected ones

    """
    pass


def _get_names(filename):
    """Return list of variable names."""
    with open(filename, 'rb') as f:
        for line in f:
            if line.decode().startswith('$Names='):
                return line.decode().split('=')[1].strip().split(';')
    raise Exception('No field names were found.')


def get_qso_log_chi2_qsonu(qso_model):
    """Natural log of goodness of fit of qso-model given fixed parameters."""
    return qso_model['log_chi2_qsonu']


@classmethod
def connect(cls, *args, **kwargs):
    """
        Should take in connection parameters
        """
    raise NotImplementedError


def _is_namespace_visible(context, namespace, status=None):
    """Return True if the namespace is visible in this context."""
    if context.is_admin:
        return True
    if namespace['owner'] is None:
        return True
    if 'visibility' in namespace:
        if namespace['visibility'] == 'public':
            return True
    if context.owner is not None:
        if context.owner == namespace['owner']:
            return True
    return False


def load_handlers(name):
    """Load the (URL pattern, handler) tuples for each component."""
    mod = __import__(name, fromlist=['default_handlers'])
    return mod.default_handlers


def _create_kaldi_wav_scp_file(wav_path, scp_path, fileid):
    """ create a scp file for getting the .wav for kaldi
    Arguments:
    wav_path -- path to the wav file
    scp_path -- path where the .scp file will be created
    fileid -- the unique name for identify the file
    """
    scp_content = '{} {}'.format(fileid, wav_path)
    with open(scp_path, 'w') as f:
        f.write(scp_content)


def delete_option_group(OptionGroupName=None):
    """
    Deletes an existing option group.
    See also: AWS API Documentation

    Examples
    This example deletes the specified option group.
    Expected Output:

    :example: response = client.delete_option_group(
        OptionGroupName='string'
    )

    :type OptionGroupName: string
    :param OptionGroupName: [REQUIRED]
            The name of the option group to be deleted.
            Note
            You cannot delete default option groups.

    :return: response = client.delete_option_group(
        OptionGroupName='mydboptiongroup',
    )

    print(response)

    """
    pass


def is_git_repository(url):
    """
    It returns if the url is a git repository.
    :param url: the url to check if it is a git repo
    :return: True/False
    """
    return url.startswith(('git://', 'git+http://', 'git+https:/')
        ) or url.endswith('.git')


def append(nodelist, node, label=None, sep='_'):
    """
    Append function to automate the naming of list elements in Containers.

    :Arguments:
        - `nodelist` : List containing nodes for Container.
        - `node` : Node to be added to list.
        - `label` : Label to be appended to list (If not passed,
        defaults to element number).
        - `sep` : Separator character for label (defaults to underscore).

    :Return:
        - `nodelist` : Passed list with node added.

    """
    nname = node.__name__
    label = label or len(nodelist)
    ind = nname.rfind(sep)
    node.__name__ = nname[:ind] + sep + str(label)
    nodelist.append(node)
    return nodelist


def get_machine_revision():
    """
    Get the machine revision.

    A return value of None indicates an error (possibly because its
    not running on an RPI).
    Otherwise the return value is the revision code.

    """
    revision_code = None
    try:
        with open('/proc/cpuinfo', 'rb') as fp:
            for line in fp:
                if b':' not in line:
                    continue
                key, _, value = line.partition(b':')
                key = key.strip().lower()
                value = value.strip().lower()
                if key == b'revision':
                    revision_code = value
                    break
    except IOError:
        return None
    else:
        if isinstance(revision_code, bytes):
            return revision_code.decode('utf-8')
        return revision_code


def custom(b, *args, **kwargs):
    """
    [NOT IMPLEMENTED]

    args can be
    - 2 ConstraintParameters (or parameters which need param.to_constraint()) (lhs, rhs)
    - 2 parsable strings (lhs, rhs)
    - single parsable string (lhs, rhs = args[0].split('=')

    :raise NotImplementedError: because it isn't
    """
    raise NotImplementedError('custom constraints not yet supported')


def strip_transient(nb):
    """Strip transient values that shouldn't be stored in files.

    This should be called in *both* read and write.
    """
    nb.pop('orig_nbformat', None)
    nb.pop('orig_nbformat_minor', None)
    for ws in nb['worksheets']:
        for cell in ws['cells']:
            cell.get('metadata', {}).pop('trusted', None)
            cell.pop('trusted', None)
    return nb


@classmethod
def fromtitles(cls, wiki, things=None):
    """Set up the Queue, optionally initialized with an iterable,
        all of whose arguments will be converted to a Page if possible.
        """
    return cls(wiki, things or [], wiki.page)


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

        :param str val:
        :rtype: LookupError
        """
    return cls('malformed_path', val)


@staticmethod
def set_access_key(config_dict, key_id, key_secret):
    """set id and secret of config's default access key"""
    if 'access_key' in config_dict:
        print('Existing access key overwritten.')
    else:
        print('Access key set.')
    config_dict['access_key'] = {key_id: key_secret}
    return config_dict


def mV_km_nT2ohms(zs):
    """Convert imp. tensor(s) from mV/km/nT to ohms"""
    return zs / 796.0


@classmethod
def from_username(cls, insta, username: str):
    """Returns a Post instance from username."""
    profile = cls(insta, {'username': username})
    profile._obtain_full_data()
    return profile


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

        :param FileRequestCreateType val:
        :rtype: EventType
        """
    return cls('file_request_create', val)


def handles_request_head(request_func):
    """
    This function decorator may be used to mark a method as usable for
    intercepting request head content.

    handles_request_head will accept an HttpRequest object and implement
    the logic that will define the FilterActions to be applied
    to the request
    """
    request_func._handles_request_head = True
    return request_func


def delete_user(user):
    """Delete the given user.

        :param user: The user to delete.
        :type user: `IUser`.
        """


def customized_warning(message, category=UserWarning, filename='', lineno=-
    1, file=None, line=None):
    """
    Customized function to display warnings.
    Monkey patch for `warnings.showwarning`.
    """
    print('WARNING: {0}'.format(message))


def center_text(message='Hello World!') ->str:
    """Takes a string and returns the centered result as a string.

    Parameters
    ----------
    message: (str)
        The message to center

    Examples
    --------
    Printing someones name centered in terminal.

    ```
    >> from sdu.terminal import center_text

    >> name = input('what is your name?:')

    >> print(center_text(name))
    ```

    Returns
    -------
    str:
        The message string centered.

    """
    import shutil
    columns = shutil.get_terminal_size().columns
    return message.center(columns)


def read_settings(template_xml):
    """
    Read the memory settings from the template file
    """
    rv = dict()
    for template in template_xml.findall('server-template'):
        for server in template.findall('server'):
            for option in server.findall('option'):
                o = option.text
                if o.startswith('-Xmx') | o.startswith('-XX'):
                    rv.setdefault(server.get('id'), []).append(o)
    return rv


def _check_improve_clusters(new_tstat_mean: float, mean_redo_tstat: float,
    old_cluster: tuple, new_cluster: tuple) ->tuple:
    """
    Checks cluster improvement condition based on t-statistic.
    :param new_tstat_mean: (float) t-statistics
    :param mean_redo_tstat: (float) average t-statistcs for cluster improvement
    :param old_cluster: (tuple) old cluster correlation matrix, optimized clusters, silh scores
    :param new_cluster: (tuple) new cluster correlation matrix, optimized clusters, silh scores
    :return: (tuple) cluster
    """
    if new_tstat_mean > mean_redo_tstat:
        return old_cluster
    return new_cluster


def clean_link(link):
    """Removes leading and trailing whitespace and punctuation"""
    return link.strip('\t\r\n \'"\x0c')


def s_one_one(topics):
    """Perform segmentation on a list of topics.
    Segmentation is defined as
    :math:`s_{one} = {(W', W^{*}) | W' = {w_i}; W^{*} = {w_j}; w_{i}, w_{j} \\in W; i \\neq j}`.

    Parameters
    ----------
    topics : list of `numpy.ndarray`
        List of topics obtained from an algorithm such as LDA.

    Returns
    -------
    list of list of (int, int).
        :math:`(W', W^{*})` for all unique topic ids.

    Examples
    -------
    .. sourcecode:: pycon

        >>> import numpy as np
        >>> from gensim.topic_coherence import segmentation
        >>>
        >>> topics = [np.array([1, 2, 3]), np.array([4, 5, 6])]
        >>> segmentation.s_one_one(topics)
        [[(1, 2), (1, 3), (2, 1), (2, 3), (3, 1), (3, 2)], [(4, 5), (4, 6), (5, 4), (5, 6), (6, 4), (6, 5)]]

    """
    s_one_one_res = []
    for top_words in topics:
        s_one_one_t = []
        for w_prime_index, w_prime in enumerate(top_words):
            for w_star_index, w_star in enumerate(top_words):
                if w_prime_index == w_star_index:
                    continue
                else:
                    s_one_one_t.append((w_prime, w_star))
        s_one_one_res.append(s_one_one_t)
    return s_one_one_res


@classmethod
def from_edges(cls, edges):
    """Form a Graph instance from the given {from: (to1, to2)} dict.

        The given 'edges' dictionary includes a key for each node from
        which a transition might originate. The corresponding value is
        either a node or a tuple of nodes; the graph includes an edge
        from the key node to each node in the value. For example, the
        dict {"A": "B", "B", ("C", "D")} defines 3 edges: A to B,
        B to C and B to D.
        """
    if edges is None:
        edges = {}
    states = set()
    distances = {}
    next = {}
    for k, v in edges.items():
        states.add(k)
        distances[k, k] = 0
        if not isinstance(v, (list, tuple)):
            v = v,
        for s in v:
            states.add(s)
            distances[k, s] = 1
            next[k, s] = s
    for k in states:
        for i in states:
            for j in states:
                segment1 = distances.get((i, k))
                if segment1 is None:
                    continue
                segment2 = distances.get((k, j))
                if segment2 is None:
                    continue
                candidate_distance = segment1 + segment2
                curpair = i, j
                current_distance = distances.get(curpair)
                if (current_distance is None or current_distance >
                    candidate_distance):
                    distances[curpair] = candidate_distance
                    next[curpair] = next.get((i, k), k)
    return cls(next)


@classmethod
def merge(cls, trees):
    """
        Merge a collection of AttrTree objects.
        """
    first = trees[0]
    for tree in trees:
        first.update(tree)
    return first


@classmethod
def cql_parameterized_type(cls):
    """
        There is no CQL notation for Composites, so we override this.
        """
    typestring = cls.cass_parameterized_type(full=True)
    return "'%s'" % (typestring,)


def _handle_shape(X, t, name):
    """My version of the shape extracting function. """
    if name == 'obs_mat':
        if len(X.shape) == 4:
            return X[t, ...]
        else:
            return X


def discard_events(library, session, event_type, mechanism):
    """Discards event occurrences for specified event types and mechanisms in a session.

    Corresponds to viDiscardEvents function of the VISA library.

    :param library: the visa library wrapped by ctypes.
    :param session: Unique logical identifier to a session.
    :param event_type: Logical event identifier.
    :param mechanism: Specifies event handling mechanisms to be dicarded.
                      (Constants.VI_QUEUE, .VI_HNDLR, .VI_SUSPEND_HNDLR, .VI_ALL_MECH)
    :return: return value of the library call.
    :rtype: :class:`pyvisa.constants.StatusCode`
    """
    return library.viDiscardEvents(session, event_type, mechanism)


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 __parseWord__(word):
    """Parse a word from a tablefile"""
    word = word.strip()
    if len(word) == 0:
        return None
    if word[-1] == '"' and word[0] == '"':
        return word[1:-1]
    try:
        ret = float(word)
        return float(ret)
    except:
        return word


def large_database_change():
    """
        Call this when the database has changed substantially,
        and it would be a good time to perform any updates or
        optimizations.
        """


def openFileForReading(segments, utf8=False):
    """
        Return a file object for reading the file.
        """


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


def local_hour_angle(apparent_sidereal_time, observer_longitude,
    sun_right_ascension):
    """Measured westward from south"""
    H = apparent_sidereal_time + observer_longitude - sun_right_ascension
    return H % 360


def suggestfields():
    """
  Fields available in ``gbif_suggest()`` function
  """
    return ['key', 'datasetTitle', 'datasetKey', 'nubKey', 'parentKey',
        'parent', 'kingdom', 'phylum', 'class', 'order', 'family', 'genus',
        'species', 'kingdomKey', 'phylumKey', 'classKey', 'orderKey',
        'familyKey', 'genusKey', 'speciesKey', 'species', 'canonicalName',
        'authorship', 'accordingTo', 'nameType', 'taxonomicStatus', 'rank',
        'numDescendants', 'numOccurrences', 'sourceId',
        'nomenclaturalStatus', 'threatStatuses', 'synonym',
        'higherClassificationMap']


@staticmethod
def dataframe_split(data_frame, remove_columns):
    """
        Take a dataframe and extract specific columns. Return the dataframe, minus those columns, and a second
        dataframe which is only those columns.
        :param data_frame: pd.DataFrame
        :param remove_columns: list(str)
        :return data_frame, data_frame_two: pd.DataFrame, pd.DataFrame
        """
    data_frame_two = data_frame.loc[:, (remove_columns)].copy()
    data_frame = data_frame.drop(remove_columns, axis=1)
    return data_frame, data_frame_two


def add(option):
    """
        Add a ready option to the pool
        """


def write_vec(f, vec, name, vec_type):
    """
    Write vector to file
    """
    f.write('%s %s[%d] = {\n' % (vec_type, name, len(vec)))
    for i in range(len(vec)):
        if vec_type == 'c_float':
            f.write('(c_float)%.20f,\n' % vec[i])
        else:
            f.write('%i,\n' % vec[i])
    f.write('};\n')


def _nextpow2(i):
    """Find next power of 2."""
    n = 1
    while n < i:
        n *= 2
    return n


def is_matching(edges):
    """Determines whether the given set of edges is a matching.

    A matching is a subset of edges in which no node occurs more than
    once.

    Parameters
    ----------
    edges : iterable
        A iterable of edges.

    Returns
    -------
    is_matching : bool
        True if the given edges are a matching.

    Example
    -------
    This example checks two sets of edges, both derived from a
    single Chimera unit cell, for a matching. Because every node in a Chimera
    unit cell connects to four other nodes in the cell, the first set, which
    contains all the edges, repeats each node 4 times; the second is a subset
    of those edges found using the `min_maximal_matching()` function.

    >>> import dwave_networkx as dnx
    >>> G = dnx.chimera_graph(1, 1, 4)
    >>> dnx.is_matching(G.edges())
    False
    >>> dnx.is_matching({(0, 4), (1, 5), (2, 7), (3, 6)})
    True

    """
    return len(set().union(*edges)) == len(edges) * 2


def get_segmentation_from_mst(mst, number):
    """Get a segmentation from a MST

    If the MST has 5 strokes and a spanning tree like
    1-       3-4-5
    2-/
    the number 3 (0011) would mean that the 0th edge
    and the 1st edge get cut. Lets say that the edge 0 is next to node 1 and
    edge 1 is next to node 2. Then the resulting segmentation would be
    [[1], [2], [3, 4, 5]]

    Parameters
    ----------
    mst :
        Minimum spanning tree
    number : int ({0, ..., 2^(edges in MST)-1})
        The number of the segmentation.
    """
    pass


def asunicode(s):
    """Force a string to be a unicode instance.

    :param s: any value
    :rtype: str

    If `s` is not already an unicode string, it is assumed it's
    an ``utf-8`` encoded string, a thus converted to unicode and
    returned. Otherwise `s` is returned as is::

      >>> assert asunicode(None) is None
      >>> assert not isinstance(asunicode(b'ascii'), bytes)
    """
    if s is None:
        return None
    elif isinstance(s, bytes):
        return s.decode('utf-8')
    else:
        return str(s)


def dockerignore(filename='.dockerignore'):
    """
    Returns a simple Python `.dockerignore`
    """
    with open(filename, 'w') as f:
        f.write(
            """__pycache__
*.pyc
*.pyo
*.pyd
.Python
env
pip-log.txt
pip-delete-this-directory.txt
.tox
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*,cover
*.log
.git"""
            )


@classmethod
def __quit_game(cls):
    """
        if pressed quit key
        call the engine's method to quit
        """
    cls.engine.end_game()


def pin(clear: bool=False):
    """Set/clear selected UV vertices as anchored between multiple unwrap operations

    :param clear: Clear, Clear pinning for the selection instead of setting it
    :type clear: bool
    """
    pass


def get_all(isamAppliance, check_mode=False, force=False):
    """
    Get management authorization - roles
    """
    return isamAppliance.invoke_get('Get management authorization - roles',
        '/authorization/roles/v1')


def broadcast_logical_or(lhs=None, rhs=None, out=None, name=None, **kwargs):
    """Returns the result of element-wise **logical or** with broadcasting.

    Example::

       x = [[ 1.,  1.,  0.],
            [ 1.,  1.,  0.]]

       y = [[ 1.],
            [ 0.]]

       broadcast_logical_or(x, y) = [[ 1.,  1.,  1.],
                                     [ 1.,  1.,  0.]]

    Defined in src/operator/tensor/elemwise_binary_broadcast_op_logic.cc:L172

    Parameters
    ----------
    lhs : NDArray
        First input to the function
    rhs : NDArray
        Second input to the function

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

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


def hash_password(plaintext_password=''):
    """
    Create a password hash from a given string for protecting a worksheet
    only. This will not work for encrypting a workbook.

    This method is based on the algorithm provided by
    Daniel Rentz of OpenOffice and the PEAR package
    Spreadsheet_Excel_Writer by Xavier Noguer <xnoguer@rezebra.com>.
    See also http://blogs.msdn.com/b/ericwhite/archive/2008/02/23/the-legacy-hashing-algorithm-in-open-xml.aspx
    """
    password = 0
    for idx, char in enumerate(plaintext_password, 1):
        value = ord(char) << idx
        rotated_bits = value >> 15
        value &= 32767
        password ^= value | rotated_bits
    password ^= len(plaintext_password)
    password ^= 52811
    return str(hex(password)).upper()[2:]


def dumb_objective(x, y):
    """Returns 0 in a way that makes everyone happy.

    Keras requires outputs and objectives but we're training purely upon the
    loss expressed by the regularizers.
    """
    return 0.0 * y + 0.0 * x


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


@staticmethod
def result_sorter(result):
    """
        Method to sort the results for the refmap. Order:
        - CCode does not contain "x", "P", "p" (i.e. fragments on opposite strand or
        polymerase run-on fragments)
        - Exonic F1 (e_f1)
        - Junction F1 (j_f1)
        - "f" in ccode (i.e. transcript is a fusion)
        - Nucleotide F1 (n_f1)

        :param result: a resultStorer object
        :type result: ResultStorer
        :return: (int, float, float, float)
        """
    bad_ccodes = ['x', 'X', 'P', 'p']
    bad_ccodes = set(bad_ccodes)
    orderer = len(set.intersection(bad_ccodes, set(result.ccode))
        ) == 0, result.j_f1, result.e_f1, result.n_f1, 'f' in result.ccode
    return orderer


def strip_quotes(string):
    """Remove both single and doulbe quotes from the beginning and ending
of given string."""
    result = string.strip('"')
    return result.strip("'")


@classmethod
def get_or_none(cls, mp, part_number):
    """Get part number."""
    return cls.query.filter_by(upload_id=mp.upload_id, part_number=part_number
        ).one_or_none()


def show_history_entries():
    """ Marks all history entries as visible
        """


def _upgrade_datamatrix_index(dm):
    """Fixes the Index object of deprecated versions of DataMatrix."""
    from datamatrix._datamatrix._index import Index
    object.__setattr__(dm, '_rowid', Index(dm._rowid._l))
    for colname, col in dm.columns:
        if hasattr(col._rowid, '_l'):
            object.__setattr__(col, '_rowid', Index(col._rowid._l))
        else:
            object.__setattr__(col, '_rowid', Index(col._rowid))
    return dm


def dump_dict(dict_input, indent=4):
    """
    辞書型変数を文字列に変換して返す
    """
    dict_work = dict(dict_input)
    """
    for key, value in six.iteritems(dict_input):
        if any([f(value) for f in (is_float, isDict, is_list_or_tuple)]):
            dict_work[key] = value
            continue

        try:
            dict_work[key] = str(value)
        except:
            dict_work[key] = str(type(value))

        dict_work[key] = _convert_dump_dict(value)
    """
    try:
        import json
        return json.dumps(dict_work, sort_keys=True, indent=indent)
    except ImportError:
        pass
    try:
        import simplejson as json
        return json.dumps(dict_work, sort_keys=True, indent=indent)
    except ImportError:
        pass
    try:
        import pprint
        return pprint.pformat(dict_work, indent=indent)
    except ImportError:
        pass
    return str(dict_work)


def split_sbtabs(sbtab_strings):
    """
    Cuts one SBtab string in single SBtab strings if necessary.

    Parameters
    ----------
    sbtab_strings: str
        SBtab table or tables in string representation.

    Returns: list
        List of SBtab tables in string representation.
    """
    sbtabs = []
    sbtab_string = ''
    counter = 1
    for row in sbtab_strings.split('\n'):
        if row.startswith('!!!') or row.startswith('"!!!'):
            continue
        if row.startswith('!!'):
            if sbtab_string == '':
                sbtab_string = row + '\n'
                continue
            else:
                try:
                    if sbtab_string.startswith('!!SBtab'):
                        sbtabs.append(sbtab_string)
                        counter += 1
                    sbtab_string = row + '\n'
                except:
                    print('Warning: Could not write SBtab %s' % counter)
                    counter += 1
        else:
            sbtab_string += row + '\n'
    if sbtab_string.startswith('!!SBtab'):
        sbtabs.append(sbtab_string)
    return sbtabs


def is_list_block(doc, pos, tokenizer):
    """Returns True if pos is in list block"""
    pos = doc.gettol(pos)
    while pos:
        pos -= 1
        tol = doc.gettol(pos)
        s = doc.gettext(tol, pos).rstrip()
        if not s:
            continue
        token = tokenizer.get_token_at(doc, tol)
        if token is tokenizer.tokens.list:
            return True
        if s[0] not in ['\t ']:
            break
        pos = tol


def SFM(val):
    """SpaceFlightMission"""
    return val


@classmethod
def user_model(cls):
    """Return the user model"""
    raise NotImplementedError('Implement in subclass')


@classmethod
def check(cls, config):
    """Run checks on a SAM input json config.

        Parameters
        ----------
        config : dict
            Extracted SAM technology input config in dict form.
        """
    c = cls(config)
    c._run_checks()


def create_fastq_line(read_id, sequence, q_values):
    """Create a fastq string from the necessary fields. Do not include newlines!

    :param read_id: unique identifier for read
    :param sequence: sequence of nucleotides
    :param q_values: quality score values associated with the sequence
    """
    assert read_id.find('\n') == -1, 'Remove newline characterss from read_id'
    assert sequence.find('\n') == -1, 'Remove newline characters from sequence'
    assert q_values.find('\n') == -1, 'Remove newline characters from q_values'
    assert len(sequence) == len(q_values
        ), 'sequence and q_values must to be the same size'
    if not read_id.startswith('@'):
        read_id = '@' + read_id
    line1 = read_id + '\n'
    line2 = sequence + '\n'
    line3 = '+\n'
    fastq = line1 + line2 + line3 + q_values
    return fastq


def add_arg(func, *args, **kwargs):
    """Bind CLI arguments to a shell.py `do_foo` function."""
    if not hasattr(func, 'arguments'):
        func.arguments = []
    if (args, kwargs) not in func.arguments:
        func.arguments.insert(0, (args, kwargs))


def main(project_name, dataset_name, item_remote_path):
    """
    Download and show an image with it's annotations
    :return:
    """
    import dtlpy as dl
    import numpy as np
    from PIL import Image
    project = dl.projects.get(project_name=project_name)
    dataset = project.datasets.get(dataset_name=dataset_name)
    item = dataset.items.get(filepath=item_remote_path)
    buffer = item.download(save_locally=False)
    image = Image.open(buffer)
    annotations = item.annotations.show(width=image.size[0], height=image.
        size[1], thickness=3)
    annotations = Image.fromarray(annotations.astype(np.uint8))
    annotations.show()
    image.show()
    image.paste(annotations, (0, 0), annotations)
    image.show()


def get_fqn(obj):
    """
    This function tries to determine the fully qualified name (FQN) of the callable that is provided.
    It only works for classes, methods and functions.
    It is unable to properly determine the FQN of class instances, static methods and class methods.
    """
    path = [getattr(obj, '__module__', None)]
    qualname = getattr(obj, '__qualname__', None)
    if qualname:
        path.append(qualname.replace('<locals>.', ''))
        im_self = getattr(obj, '__self__', None)
        im_class = getattr(im_self, '__class__', None)
        if im_self and im_class:
            path = [getattr(im_class, '__module__', None), getattr(im_class,
                '__name__', None), getattr(obj, '__name__', None)]
    else:
        im_class = getattr(obj, 'im_class', None)
        im_class_module = getattr(im_class, '__module__', None)
        if im_class and im_class_module:
            path = [im_class_module]
        path.append(getattr(im_class, '__name__', None))
        path.append(getattr(obj, '__name__', None))
    return '.'.join(filter(None, path))


def generate_inverse(conversions):
    """Generate all simple inverse conversions.

    A simple inverse conversion is something we can obtain by doing
    a ``1 / unit`` type of conversion.

    Parameters
    ----------
    conversions : dictionary
        The unit conversions as `convert[quantity]`.
        Note that this variable will be updated by this function.

    Returns
    -------
    out : None
        Will not return anything, but will update the given parameter
        `conversions`.

    """
    newconvert = {}
    for unit in conversions:
        unit_from, unit_to = unit
        newunit = unit_to, unit_from
        if newunit not in conversions:
            newconvert[newunit] = 1.0 / conversions[unit]
    for newunit in newconvert:
        conversions[newunit] = newconvert[newunit]


def authorize_snapshot_access(SnapshotIdentifier=None,
    SnapshotClusterIdentifier=None, AccountWithRestoreAccess=None):
    """
    Authorizes the specified AWS customer account to restore the specified snapshot.
    For more information about working with snapshots, go to Amazon Redshift Snapshots in the Amazon Redshift Cluster Management Guide .
    See also: AWS API Documentation

    :example: response = client.authorize_snapshot_access(
        SnapshotIdentifier='string',
        SnapshotClusterIdentifier='string',
        AccountWithRestoreAccess='string'
    )

    :type SnapshotIdentifier: string
    :param SnapshotIdentifier: [REQUIRED]
            The identifier of the snapshot the account is authorized to restore.

    :type SnapshotClusterIdentifier: string
    :param SnapshotClusterIdentifier: The identifier of the cluster the snapshot was created from. This parameter is required if your IAM user has a policy containing a snapshot resource element that specifies anything other than * for the cluster name.

    :type AccountWithRestoreAccess: string
    :param AccountWithRestoreAccess: [REQUIRED]
            The identifier of the AWS customer account authorized to restore the specified snapshot.
            To share a snapshot with AWS support, specify amazon-redshift-support.

    :rtype: dict
    :return: {
        'Snapshot': {
            'SnapshotIdentifier': 'string',
            'ClusterIdentifier': 'string',
            'SnapshotCreateTime': datetime(2015, 1, 1),
            'Status': 'string',
            'Port': 123,
            'AvailabilityZone': 'string',
            'ClusterCreateTime': datetime(2015, 1, 1),
            'MasterUsername': 'string',
            'ClusterVersion': 'string',
            'SnapshotType': 'string',
            'NodeType': 'string',
            'NumberOfNodes': 123,
            'DBName': 'string',
            'VpcId': 'string',
            'Encrypted': True|False,
            'KmsKeyId': 'string',
            'EncryptedWithHSM': True|False,
            'AccountsWithRestoreAccess': [
                {
                    'AccountId': 'string',
                    'AccountAlias': 'string'
                },
            ],
            'OwnerAccount': 'string',
            'TotalBackupSizeInMegaBytes': 123.0,
            'ActualIncrementalBackupSizeInMegaBytes': 123.0,
            'BackupProgressInMegaBytes': 123.0,
            'CurrentBackupRateInMegaBytesPerSecond': 123.0,
            'EstimatedSecondsToCompletion': 123,
            'ElapsedTimeInSeconds': 123,
            'SourceRegion': 'string',
            'Tags': [
                {
                    'Key': 'string',
                    'Value': 'string'
                },
            ],
            'RestorableNodeTypes': [
                'string',
            ],
            'EnhancedVpcRouting': True|False
        }
    }

    :returns:
    CreateClusterSnapshot and  CopyClusterSnapshot returns status as "creating".
    DescribeClusterSnapshots returns status as "creating", "available", "final snapshot", or "failed".
    DeleteClusterSnapshot returns status as "deleted".

    """
    pass


@classmethod
def single(C, namespace=None):
    """An element maker with a single namespace that uses that namespace as the default"""
    if namespace is None:
        B = C()._
    else:
        B = C(default=namespace, _=namespace)._
    return B


def get_axis_coords(ds, axis_name):
    """Find the name of the coordinates associated with a comodo axis.

    Parameters
    ----------
    ds : xarray.dataset or xarray.dataarray
    axis_name : str
        The name of the axis to find (e.g. 'X')

    Returns
    -------
    coord_name : list
        The names of the coordinate matching that axis
    """
    coord_names = []
    for d in ds.dims:
        axis = ds[d].attrs.get('axis')
        if axis == axis_name:
            coord_names.append(d)
    return coord_names


def get_auto_scaling_group(asg, asg_name: str):
    """Get boto3 Auto Scaling Group by name or raise exception"""
    result = asg.describe_auto_scaling_groups(AutoScalingGroupNames=[asg_name])
    groups = result['AutoScalingGroups']
    if not groups:
        raise Exception('Auto Scaling Group {} not found'.format(asg_name))
    return groups[0]


def decode_utf8(input_iterator):
    """
    Generator that decodes a utf-8 encoded
    input line by line
    """
    for l in input_iterator:
        yield l if isinstance(l, str) else l.decode('utf-8')


@staticmethod
def _safe_pop(l):
    """Safely pop from a list.

        Returns None if list empty.

        """
    return l.pop(0) if l else None


def box(w=3, h=2):
    """ Create flowchart block

        Parameters
        ----------
        w: float
            Width of box
        h: float
            Height of box

        Anchors: N, S, E, W
    """
    elem = {'name': 'FLOWBOX', 'extend': False, 'lblloc': 'center',
        'lblofst': 0, 'theta': -90}
    elem['paths'] = [[[0, 0], [0, w / 2], [h, w / 2], [h, -w / 2], [0, -w /
        2], [0, 0]]]
    elem['anchors'] = {'W': [h / 2, -w / 2], 'E': [h / 2, w / 2], 'S': [h,
        0], 'N': [0, 0]}
    elem['drop'] = [h, 0]
    return elem


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


def load_aws_s3(source_url, sink_path):
    """
    Load a file from AWS S3.

    Parameters
    ----------
    source_url : str
        Where to load the file from.
    sink_path : str
        Where the loaded file is stored.
    """
    import boto3
    url = source_url[len('s3://'):]
    bucket, key = url.split('/', 1)
    if len(key) == 0:
        raise ValueError("Key was empty for source_url='{}'".format(source_url)
            )
    client = boto3.Session().client('s3')
    response = client.get_object(Bucket=bucket, Key=key)
    body_string = response['Body'].read()
    with open(sink_path, 'wb') as f:
        f.write(body_string)


def is_indexable(e):
    """ Returns true if it is indexable
    """
    return hasattr(e, '__getitem__')


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

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

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


def every2(ol, test_func, *args):
    """
        from elist.elist import *
        def test_func(ele,index,x):
            cond1 = (ele > x)
            cond2 = (index %2 ==0)
            cond = cond1 & cond2
            return(cond)

        ol = [1,2,3,4]
        every2(ol,test_func,3)

        ol = [10,20,30,40]
        every2(ol,test_func,3)

    """
    rslt = True, None
    length = ol.__len__()
    for i in range(0, length):
        cond = test_func(ol[i], i, *args)
        if cond:
            pass
        else:
            return False, i
    return rslt


@staticmethod
def _check_jobs_submitted(status, module):
    """Check whether jobs have been submitted for a given module.

        Parameters
        ----------
        status : reV.pipeline.status.Status
            reV job status object.
        module : str
            reV module.

        Returns
        -------
        submitted : bool
            Boolean check to see if jobs have been submitted for the module arg
        """
    submitted = False
    if module in status.data:
        jobs = status.data[module]
        for job in jobs.keys():
            if job != 'pipeline_index':
                submitted = True
                break
    return submitted


@classmethod
def create(cls, d):
    """ Create a :class:`~pypot.primitive.move.Move` from a dictionary. """
    move = cls(d['framerate'])
    move._timed_positions.update(d['positions'])
    return move


def args_to_dict(args):
    """Converts request arguments to a simple dictionary. Uses only the first
    value.

    :param args: flask's request args object
    :type args: request.args
    :return: a simple dict from args
    :rtype: dict
    """
    return args.to_dict(flat=True)


def is_log_scale_matrix(matrix):
    """
    This method receives in input a matrix created as
    performance.sel(dataset=X, model=Y) with li and lj as axes.

    In case the first values is at least 2 times bigger than the second values,
    we return True and the matrix will be rescaled in
    plot_rank_confusion_matrix by applying log2; otherwise we return False
    and nothing happens.

    Parameters
    ----------
    matrix : xarray
         created as performance.sel(dataset=X, model=Y) with li and lj as axes

    Returns
    -------
    : bool
        True or False

    """
    flat = matrix.values.flatten()
    flat.sort()
    if flat[-1] / flat[-2] > 2:
        return True
    else:
        return False


def sanitize_date(date):
    """In order to have a more accurate comparison due to minimal delays
    upon publishing entries. We strip milliseconds from the dates we compare.
    :param date: datetime.datetime
    :return: datetime.datetime without milliseconds.
    """
    return date.replace(microsecond=0)


def remove_namespace(doc, namespace):
    """Remove namespace in the passed document in place."""
    ns = u'{%s}' % namespace
    nsl = len(ns)
    for elem in doc.getiterator():
        if elem.tag.startswith(ns):
            elem.tag = elem.tag[nsl:]


def properties_remove(data_path: str='', property: str=''):
    """Internal use (edit a property data_path)

    :param data_path: Property Edit, Property data_path edit
    :type data_path: str
    :param property: Property Name, Property name edit
    :type property: str
    """
    pass


def has(cls):
    """
    Check whether *cls* is a class with ``attrs`` attributes.

    :param type cls: Class to introspect.
    :raise TypeError: If *cls* is not a class.

    :rtype: bool
    """
    return getattr(cls, '__attrs_attrs__', None) is not None


def p_character_raw(p):
    """character : K_RAW STRING"""
    p[0] = [('raw', (p[2][1:-1],))]


def path_shift(script_name, path_info, shift=1):
    """ Shift path fragments from PATH_INFO to SCRIPT_NAME and vice versa.

        :return: The modified paths.
        :param script_name: The SCRIPT_NAME path.
        :param script_name: The PATH_INFO path.
        :param shift: The number of path fragments to shift. May be negative to
          change the shift direction. (default: 1)
    """
    if shift == 0:
        return script_name, path_info
    pathlist = path_info.strip('/').split('/')
    scriptlist = script_name.strip('/').split('/')
    if pathlist and pathlist[0] == '':
        pathlist = []
    if scriptlist and scriptlist[0] == '':
        scriptlist = []
    if 0 < shift <= len(pathlist):
        moved = pathlist[:shift]
        scriptlist = scriptlist + moved
        pathlist = pathlist[shift:]
    elif 0 > shift >= -len(scriptlist):
        moved = scriptlist[shift:]
        pathlist = moved + pathlist
        scriptlist = scriptlist[:shift]
    else:
        empty = 'SCRIPT_NAME' if shift < 0 else 'PATH_INFO'
        raise AssertionError('Cannot shift. Nothing left from %s' % empty)
    new_script_name = '/' + '/'.join(scriptlist)
    new_path_info = '/' + '/'.join(pathlist)
    if path_info.endswith('/') and pathlist:
        new_path_info += '/'
    return new_script_name, new_path_info


def delta_heading(coordinate1, coordinate2):
    """
    Return the change in user heading between two coordinate bearings.
    """
    delta1 = abs(coordinate1.bearing - coordinate2.bearing)
    delta2 = 360 - delta1
    return min([delta1, delta2])


@classmethod
def delete_auth_token(cls, user_id, token):
    """Deletes a given authorization token.

        :param user_id:
            User unique ID.
        :param token:
            A string with the authorization token.
        """
    cls.token_model.get_key(user_id, 'auth', token).delete()


def __le__(ref):
    """KeyReferences must be totally orderable."""


@staticmethod
def mention(user):
    """
        Mention a user in a message.  This may trigger a notification for them even if the conversation is muted.

        Args:
            user (SkypeUser): user who is to be mentioned

        Returns:
            str: tag to display the mention
        """
    return '<at id="8:{0}">{1}</at>'.format(user.id, user.name)


def listcopy(sequence):
    """Create a copy of the list, calling the copy constructor on each
    object in the list (problems when using copy.deepcopy)."""
    if not sequence:
        return []
    else:
        return [object.__class__(object) for object in sequence]


@staticmethod
def _check_band(label, band_definition):
    """Check that a proposed band definition is valid.

        Parameters
        ----------
        label : str
            The name of the new band.
        band_definition : tuple of (float, float)
            The lower and upper frequency limit of the band, in Hz.

        Raises
        ------
        ValueError
            If band definition is not properly formatted.
        """
    if not isinstance(label, str):
        raise ValueError('Band name definition is not a string.')
    if not len(band_definition) == 2:
        raise ValueError('Band limit definition is not the right size.')
    if not band_definition[0] < band_definition[1]:
        raise ValueError('Band limit definitions are invalid.')


def filename_to_domain(filename):
    """[:-4] for the .txt at end
    """
    return filename.replace('-', '/')[:-4]


def p_opt_WHERE(p):
    """opt_WHERE : WHERE expr"""
    p[0] = p[2]


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

        :param PaperDocDownloadDetails val:
        :rtype: EventDetails
        """
    return cls('paper_doc_download_details', val)


def get_catkin_cmake_args_completer_choices():
    """Get completer choices for CMake arguments for catkin packages."""
    return [' -DCATKIN_ENABLE_TESTING={flag}'.format_map(locals()) for flag in
        ('OFF', 'ON')] + [' -DCATKIN_SKIP_TESTING={flag}'.format_map(locals
        ()) for flag in ('OFF', 'ON')] + [' -DSETUPTOOLS_DEB_LAYOUT={flag}'
        .format_map(locals()) for flag in ('OFF', 'ON')]


def replace_content(content, project_vars):
    """
    Replaces variables inside the content.
    """
    for k, v in project_vars.items():
        content = content.replace(f'__{k}__', v)
    return content


def get_data(data, *keys, optional=False):
    """ 从字典数据类型中批量获取变量。get list data from dict.

    Examples::

        offset, limit, from_date, to_date = get_data(request.data, 'offset', 'limit', 'from', 'to', optional=True)

    :type data: dict
    :type keys: str
    :type optional: bool
    """
    if optional:
        return map(lambda key: data.get(key), keys)
    return map(lambda key: data[key], keys)


def get_has_next_record(rawdata=None, **kwargs):
    """Returns whether or not more wmf records exist in the rawdata."""
    try:
        return len(rawdata.peek(6)) >= 6
    except Exception:
        return False


def numseries_segment(wsize, iterable):
    """
    >>> list(numseries_segment(5, [1, 3, 5, 7]))
    [[1, 3], [5, 7]]

    :param wsize: integer
    :param iterable: must be asc ordered
    :return: a list of lists
    """
    wsize = float(wsize)
    count = 0
    chunk = list()
    for num in iterable:
        idx = int(num / wsize)
        while idx > count:
            yield chunk
            chunk = list()
            count += 1
        chunk.append(num)
    yield chunk


@staticmethod
def test_sequence(line):
    """tests the given line to only contain characters in the set [A, C, T, G]"""
    for c in line:
        if c not in ['A', 'C', 'T', 'G']:
            return False
    return True


@classmethod
def clone(cls, name, vhost, directory, origin):
    """Clone a PaaS instance's vhost into a local git repository."""
    paas_info = cls.info(name)
    if 'php' in paas_info['type'] and not vhost:
        cls.error(
            'PHP instances require indicating the VHOST to clone with --vhost <vhost>'
            )
    paas_access = '%s@%s' % (paas_info['user'], paas_info['git_server'])
    remote_url = 'ssh+git://%s/%s.git' % (paas_access, vhost)
    command = 'git clone %s %s --origin %s' % (remote_url, directory, origin)
    init_git = cls.execute(command)
    if init_git:
        cls.echo(
            'Use `git push %s master` to push your code to the instance.' %
            origin)
        cls.echo('Then `$ gandi deploy` to build and deploy your application.')


@classmethod
def from_json_type(cls, data):
    """Convert a dictionary of JSON safe data to an event"""
    data.pop('type')
    return cls(**data)


def hal_report_to_terminal(report, base_indent=0):
    """Yield lines from the HalsteadReport to print to the terminal."""
    yield 'h1: {}'.format(report.h1), (), {'indent': 1 + base_indent}
    yield 'h2: {}'.format(report.h2), (), {'indent': 1 + base_indent}
    yield 'N1: {}'.format(report.N1), (), {'indent': 1 + base_indent}
    yield 'N2: {}'.format(report.N2), (), {'indent': 1 + base_indent}
    yield 'vocabulary: {}'.format(report.vocabulary), (), {'indent': 1 +
        base_indent}
    yield 'length: {}'.format(report.length), (), {'indent': 1 + base_indent}
    yield 'calculated_length: {}'.format(report.calculated_length), (), {
        'indent': 1 + base_indent}
    yield 'volume: {}'.format(report.volume), (), {'indent': 1 + base_indent}
    yield 'difficulty: {}'.format(report.difficulty), (), {'indent': 1 +
        base_indent}
    yield 'effort: {}'.format(report.effort), (), {'indent': 1 + base_indent}
    yield 'time: {}'.format(report.time), (), {'indent': 1 + base_indent}
    yield 'bugs: {}'.format(report.bugs), (), {'indent': 1 + base_indent}


def pytest_sessionfinish(session, exitstatus):
    """Attach the exit status to the session config so we can read it later.

    We need this in order to tell whether the test run passed or not.
    """
    setattr(session.config, 'exitstatus', exitstatus)


@classmethod
def supports_replication_feature(cls, feature):
    """Check if driver class supports replication features.

        Feature is a string that must be one of:
            - v2.1
            - a/a
        """
    if feature not in cls.REPLICATION_FEATURE_CHECKERS:
        return False
    method_name = cls.REPLICATION_FEATURE_CHECKERS[feature]
    return not cls._is_base_method(method_name)


def spread(nodes, n):
    """Distrubute master instances in different nodes

    {
        "192.168.0.1": [node1, node2],
        "192.168.0.2": [node3, node4],
        "192.168.0.3": [node5, node6]
    } => [node1, node3, node5]
    """
    target = []
    while len(target) < n and nodes:
        for ip, node_group in list(nodes.items()):
            if not node_group:
                nodes.pop(ip)
                continue
            target.append(node_group.pop(0))
            if len(target) >= n:
                break
    return target


def first_solid(*tristates, default=None):
    """Utility combining multiple tri-state booleans."""
    from boltons.iterutils import first
    return first(tristates, default=default, key=lambda i: i is not None)


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


@classmethod
def add_to_schema(cls, schema_entries):
    """
        Add this type to the wsdl.
        """


def get_default_parser():
    """ Default command line argument parser """
    from glumpy.app.parser import get_default
    return get_default()


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


def parsenotagsintoot(config):
    """Parse configuration values and get values of the the no_tags_in_toot option of the hashtaglist section"""
    section = 'hashtaglist'
    option = 'no_tags_in_toot'
    notagsintoot = False
    if config.has_option(section, option):
        notagsintoot = config.getboolean(section, option)
    return notagsintoot


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


def all():
    """Returns an interator on all (index, starting element) of the
        batch.
        """


@staticmethod
def _instance_in_array(object_instance, object_array):
    """Check if a specific object instance is already in an array.

        This can be much faster than  `if object_instance in object_array`
        when you expect to be testing a lot of the same instance of an object for
        inclusion in an array since the builtin method uses an == operator to
        test inclusion.
        """
    for val in object_array:
        if val is object_instance:
            return True
    return False


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


def _find(seq, val):
    """
    Search sequence 'seq' for val.  This behaves like str.find(): if not found,
    -1 is returned instead of throwing an exception.

    Args:
        seq: The sequence to search
        val: The value to search for

    Returns:
        int: The index of the value if found, or -1 if not found
    """
    try:
        return seq.index(val)
    except ValueError:
        return -1


def getscan(indir, depth=1, accu=True):
    """
    Get scan of a Microsoft Word file.
    indir is the inputing directory,and depth indicates how deep you want to know.
    e.g.with depth=3, you'll get all the Heading 1, Heading 2 as well as Heading 3 of the file.
    and,if accu is False, you'll get Heading 3 only.
    """
    resu = []
    import docx
    f = docx.Document(indir)
    for i in f.paragraphs:
        if accu == False:
            name_left = 'Heading '
            name_right = str(depth)
            if i.style.name == name_left + name_right:
                resu.append(i.text)
        else:
            j = 1
            for j in range(1, depth + 1):
                name_left = 'Heading '
                name_right = str(j)
                if i.style.name == name_left + name_right:
                    resu.append(i.text)
                    j += 1
    return resu


def human_readable_number(number, suffix=''):
    """
    Format the given number into a human-readable string.

    Code adapted from http://stackoverflow.com/a/1094933

    :param variant number: the number (int or float)
    :param string suffix: the unit of the number
    :rtype: string
    """
    for unit in ['', 'K', 'M', 'G', 'T', 'P', 'E', 'Z']:
        if abs(number) < 1024.0:
            return '%3.1f%s%s' % (number, unit, suffix)
        number /= 1024.0
    return '%.1f%s%s' % (number, 'Y', suffix)


def paint_mask_extract(mask_threshold: float=0.5, add_boundary_loop: bool=
    True, smooth_iterations: int=4, apply_shrinkwrap: bool=True,
    add_solidify: bool=True):
    """Create a new mesh object from the current paint mask

    :param mask_threshold: Threshold, Minimum mask value to consider the vertex valid to extract a face from the original mesh
    :type mask_threshold: float
    :param add_boundary_loop: Add Boundary Loop, Add an extra edge loop to better preserve the shape when applying a subdivision surface modifier
    :type add_boundary_loop: bool
    :param smooth_iterations: Smooth Iterations, Smooth iterations applied to the extracted mesh
    :type smooth_iterations: int
    :param apply_shrinkwrap: Project to Sculpt, Project the extracted mesh into the original sculpt
    :type apply_shrinkwrap: bool
    :param add_solidify: Extract as Solid, Extract the mask as a solid object with a solidify modifier
    :type add_solidify: bool
    """
    pass


def correlate_dicts(dicts, key):
    """Correlate several dicts under one superdict.

    If you have several dicts each with a 'name' key, this
    puts them in a container dict keyed by name.

    Example::

        >>> d1 = {"name": "Fred", "age": 41}
        >>> d2 = {"name": "Barney", "age": 31}
        >>> flintstones = correlate_dicts([d1, d2], "name")
        >>> sorted(flintstones.keys())
        ['Barney', 'Fred']
        >>> flintstones["Fred"]["age"]
        41

    If you're having trouble spelling this method correctly, remember:
    "relate" has one 'l'.  The 'r' is doubled because it occurs after a prefix.
    Thus "correlate".
    """
    ret = {}
    i = 0
    for d in dicts:
        try:
            my_key = d[key]
        except KeyError:
            msg = "'dicts' element %d contains no key '%s'"
            tup = i, key
            raise KeyError(msg % tup)
        ret[my_key] = d
        i += 1
    return ret


def func_not(parser, x):
    """Returns true, if ``x`` is empty."""
    if not x:
        return '1'
    else:
        return ''


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

        :param MicrosoftOfficeAddinChangePolicyType val:
        :rtype: EventType
        """
    return cls('microsoft_office_addin_change_policy', val)


def tag_to_str(tag):
    """Convert a DICOM tag to a string representation using the group and
    element hex values seprated by an underscore."""
    return '%#X_%#X' % (tag.group, tag.elem)


def bin2dec(x):
    """Convert ``x``, an array of "bits" (MSB first), to it's decimal value."""
    bits = []
    bits.extend(x)
    bits.reverse()
    multi = 1
    value = 0
    for b in bits:
        value += b * multi
        multi *= 2
    return value


@classmethod
def from_toml(cls, f):
    """

        Get information from toml file.

        Parameters
        ----------
        f: str
            Name of input toml File

        Returns
        -------
        cls.from_dict: DFTConfigParams object
            Parameters for DFT solver
        """
    import toml
    return cls(toml.load(f))


def removeWriter(writer):
    """
        Removes an object previously added with L{addWriter}.

        @return: C{None}.
        """


def admin_actions(context):
    """
    Track the number of times the action field has been rendered on the page,
    so we know which value to use.
    """
    context['action_index'] = context.get('action_index', -1) + 1
    return context


def metric_mul(key, value=1):
    """Multiplies the specified metric key value by the specified value.

    :param str|unicode key:

    :param int value:

    :rtype: bool
    """
    return False


def chunks(it, size):
    """
    Chunk a generator into a given size (last chunk might be smaller)
    """
    buf = []
    for s in it:
        buf.append(s)
        if len(buf) == size:
            yield buf
            buf = []
    if len(buf) > 0:
        yield buf


def is_cap_used(use_caps, i):
    """Returns ``True`` if a cap is used.

    Parameters
    ----------
    use_caps : :class:`int`
        Bit mask indicating which cap is used.
    i : :class:`int`
        Number indicating which cap we are interested in.

    Returns
    -------
    :class:`bool`
        ``True`` if a cap is used.
    """
    return use_caps & 1 << i != 0


def poly_td(data):
    """
    Polynomial time domain solvent subtraction - Not Implemented
    """
    raise NotImplementedError


def have_fields_changed(obj, *fields):
    """Returns True if all the specified fields on an object have changed compared the current database version."""
    if not obj.pk:
        return False
    try:
        current_obj = obj.__class__.objects.only(*fields).get(pk=obj.pk)
        for field in fields:
            if getattr(obj, field) == getattr(current_obj, field):
                return False
        return True
    except:
        return False


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

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

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


def dirhandler(directory, defaultdir):
    """
    If directory is None, turn it into defaultdir.

    :param directory: Target directory.
    :type directory: str

    :param defaultdir: Default directory.
    :type defaultdir: str
    """
    directory = defaultdir if directory is None else directory
    return directory


def on_disconnect():
    """ Called when the client connection lost."""
    print('connect lost')


def verify_operator(operator):
    """
    Checks that ``operator`` is one of the allowed strings.
    Legal operators include the following strings:

    - '='
    - '<='
    - '>='
    - '<'
    - '>'
    - '<>'
    - 'like'
    - 'regexp'
    - 'is null'
    - 'is not null'

    EXAMPLES::

        sage: from sage.databases.sql_db import verify_operator
        sage: verify_operator('<=')
        True
        sage: verify_operator('regexp')
        True
        sage: verify_operator('is null')
        True
        sage: verify_operator('not_an_operator')
        Traceback (most recent call last):
        ...
        TypeError: not_an_operator is not a legal operator.
    """
    binaries = ['=', '<=', '>=', 'like', '<', '>', '<>', 'regexp']
    unaries = ['is null', 'is not null']
    if operator not in binaries and operator not in unaries:
        raise TypeError('%s is not a legal operator.' % operator)
    return True


def dot_to_dict(values):
    """Convert dot notation to a dict. For example: ["token.pos", "token._.xyz"]
    become {"token": {"pos": True, "_": {"xyz": True }}}.

    values (iterable): The values to convert.
    RETURNS (dict): The converted values.
    """
    result = {}
    for value in values:
        path = result
        parts = value.lower().split('.')
        for i, item in enumerate(parts):
            is_last = i == len(parts) - 1
            path = path.setdefault(item, True if is_last else {})
    return result


@staticmethod
def match(elem, seq_expr):
    """
        Return True if elem (an element of elem_list) matches seq_expr, an element in self.sequence
        """
    if type(seq_expr) is str:
        if seq_expr == '.':
            return True
        elif seq_expr == '\\d':
            return elem.is_numerical()
        elif seq_expr == '\\D':
            return not elem.is_numerical()
        else:
            raise LookupError('{0} is not a valid wild-card'.format(seq_expr))
    else:
        return elem == seq_expr


def is_model_instance(engine):
    """
    Determines if `engine` is an instance of an izzy model instance.

    Parameters
    ----------
    engine : object
        An izzy model instance.

    Returns
    -------
    bool
        True or False if engine is an izzy instance.
    """
    return isinstance(engine, object) & (getattr(engine, '_package', None) ==
        'izzy')


@classmethod
def create_ikepolicy(cls, name):
    """Wrapper utility that returns a test ike policy."""
    body = cls.client.create_ikepolicy(name=name)
    ikepolicy = body['ikepolicy']
    cls.ikepolicies.append(ikepolicy)
    return ikepolicy


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 closing_fd(fd):
    """
        Inform the loop that the file descriptor *fd* is about to be closed.

        The loop may choose to schedule events to be delivered to any active
        IO watchers for the fd. libev does this so that the active watchers
        can be closed.

        :return: A boolean value that's true if active IO watchers were
           queued to run. Closing the FD should be deferred until the next
           run of the eventloop with a callback.
        """


def getState():
    """ get the state of the queue, i.e. its contents """


def _superclasses(obj, cls):
    """return remaining classes in object's MRO after cls"""
    mro = type(obj).__mro__
    return mro[mro.index(cls) + 1:]


def print_latex(formula):
    """
    Print a LaTeX - formatted version of the formula

    Examples
    ---------
    >>> print_latex('Fe2SO4')
    Fe_2SO_4
    >>> print_latex('CH3CH2CH3')
    CH_3CH_2CH_3
    >>> print_latex('Fe2(OH)2+2')
    Fe_2(OH)_2^+^2

    """
    output = ''
    for i in range(len(formula)):
        if formula[i].isnumeric() and i > 0:
            if formula[i - 1] == '+' or formula[i - 1] == '-':
                output += '^'
            else:
                output += '_'
        if formula[i] == '+' or formula[i] == '-':
            output += '^'
        output += formula[i]
    print(output)


def slope_inv(p1, p2):
    """Returns the inverse of the slope of the line from p1 to p2."""
    return float(p2[0] - p1[0]) / (p2[1] - p1[1])


def _present_config_results(config_records, resource_ids):
    """
    If resource_id is in config_results add to dictionary and return dictionary

    :param config_records: config compliance records
    :param resource_ids: list of resource ids
    :returns: dictionary of resource_id: compliance_type
    """
    found_ids = {}
    for config_records in config_records:
        config_record_id = config_records['EvaluationResultIdentifier'][
            'EvaluationResultQualifier']['ResourceId']
        if config_record_id in resource_ids:
            found_ids[config_record_id] = config_records['ComplianceType']
    return found_ids


def check_data(whois_str):
    """
    Delete comment strings.
    """
    g = ''
    for line in whois_str.splitlines(True):
        if not line.startswith('%'):
            g += line
    return g


def yearSalary(monthSalary):
    """根据传入的月薪的值，计算出年薪：monthSalary*12"""
    return monthSalary


def gather_row(data, row_index):
    """Slice out the data given the row index.

    Parameters
    ----------
    data : Tensor
        The data tensor
    row_index : Tensor
        A 1-D integer tensor containing which rows to be sliced out.

    Returns
    -------
    Tensor
        The sliced data. The first dimension should equal to ``len(row_index)``.
    """
    pass


def parse_negotiation(value):
    """Parse Content Negotiation headers to list of value, quality tuples."""
    values = []
    for it in value.split(','):
        pair = it.split(';')
        if pair[0] == it:
            values.append((it, 1.0))
            continue
        try:
            quality = float(pair[1].split('=')[1])
        except (IndexError, ValueError):
            quality = 1.0
        values.append((pair[0], quality))
    return values


@classmethod
def __factory(cls, data):
    """
        This factory makes that any returned value is a measure
        instead of a float.
        """
    return cls(data)


def append_slash(url):
    """Make sure we append a slash at the end of the URL otherwise we
    have issues with urljoin Example:
    >>> urlparse.urljoin('http://www.example.com/api/v3', 'user/1/')
    'http://www.example.com/api/user/1/'
    """
    if url and not url.endswith('/'):
        url = '{0}/'.format(url)
    return url


def get_api(name):
    """Look up skin api by name."""


def misplaced_comparison_constant(editor, item):
    """ Pylint method to fix misplaced_comparison_constant error """
    line_no = item.line_no
    return line_no, 0


@classmethod
def load_image(cls, filename, height=1, array=False, bounds=None, bare=
    False, **kwargs):
    """
        Returns an raster element or raw numpy array from a PNG image
        file, using matplotlib.

        The specified height determines the bounds of the raster
        object in sheet coordinates: by default the height is 1 unit
        with the width scaled appropriately by the image aspect ratio.

        Note that as PNG images are encoded as RGBA, the red component
        maps to the first channel, the green component maps to the
        second component etc. For RGB elements, this mapping is
        trivial but may be important for subclasses e.g. for HSV
        elements.

        Setting bare=True will apply options disabling axis labels
        displaying just the bare image. Any additional keyword
        arguments will be passed to the Image object.
        """
    try:
        from matplotlib import pyplot as plt
    except:
        raise ImportError('RGB.load_image requires matplotlib.')
    data = plt.imread(filename)
    if array:
        return data
    h, w, _ = data.shape
    if bounds is None:
        f = float(height) / h
        xoffset, yoffset = w * f / 2, h * f / 2
        bounds = -xoffset, -yoffset, xoffset, yoffset
    rgb = cls(data, bounds=bounds, **kwargs)
    if bare:
        rgb = rgb(plot=dict(xaxis=None, yaxis=None))
    return rgb


@classmethod
def _from_c(cls, ptr, iterator=None):
    """Builds the entry from a ``git_config_entry`` pointer.

        ``iterator`` must be a ``ConfigIterator`` instance if the entry was
        created during ``git_config_iterator`` actions.
        """
    entry = cls.__new__(cls)
    entry._entry = ptr
    entry.iterator = iterator
    if iterator is not None:
        entry.raw_name = entry.raw_name
        entry.raw_value = entry.raw_value
        entry.level = entry.level
    return entry


def describe_deployments(StackId=None, AppId=None, DeploymentIds=None):
    """
    Requests a description of a specified set of deployments.
    See also: AWS API Documentation

    :example: response = client.describe_deployments(
        StackId='string',
        AppId='string',
        DeploymentIds=[
            'string',
        ]
    )

    :type StackId: string
    :param StackId: The stack ID. If you include this parameter, DescribeDeployments returns a description of the commands associated with the specified stack.

    :type AppId: string
    :param AppId: The app ID. If you include this parameter, DescribeDeployments returns a description of the commands associated with the specified app.

    :type DeploymentIds: list
    :param DeploymentIds: An array of deployment IDs to be described. If you include this parameter, DescribeDeployments returns a description of the specified deployments. Otherwise, it returns a description of every deployment.
            (string) --

    :rtype: dict
    :return: {
        'Deployments': [
            {
                'DeploymentId': 'string',
                'StackId': 'string',
                'AppId': 'string',
                'CreatedAt': 'string',
                'CompletedAt': 'string',
                'Duration': 123,
                'IamUserArn': 'string',
                'Comment': 'string',
                'Command': {
                    'Name': 'install_dependencies'|'update_dependencies'|'update_custom_cookbooks'|'execute_recipes'|'configure'|'setup'|'deploy'|'rollback'|'start'|'stop'|'restart'|'undeploy',
                    'Args': {
                        'string': [
                            'string',
                        ]
                    }
                },
                'Status': 'string',
                'CustomJson': 'string',
                'InstanceIds': [
                    'string',
                ]
            },
        ]
    }

    :returns:
    execute_recipes : Execute one or more recipes. To specify the recipes, set an Args parameter named recipes to the list of recipes to be executed. For example, to execute phpapp::appsetup , set Args to {"recipes":["phpapp::appsetup"]} .
    install_dependencies : Install the stack's dependencies.
    update_custom_cookbooks : Update the stack's custom cookbooks.
    update_dependencies : Update the stack's dependencies.

    """
    pass


def update_headers(response, headers):
    """
    Helper function to update headers in the response.

    :param response: swob.Response object
    :param headers: dictionary headers
    """
    if hasattr(headers, 'items'):
        headers = headers.items()
    for name, value in headers:
        if name == 'etag':
            response.headers[name] = value.replace('"', '')
        elif name not in ('date', 'content-length', 'content-type',
            'connection', 'x-put-timestamp', 'x-delete-after'):
            response.headers[name] = value


def merge(a, b):
    """
    Merge all attributes and metadata from I{a} to I{b}.
    @param a: A I{source} object
    @type a: L{Object}
    @param b: A I{destination} object
    @type b: L{Object}
    """
    for item in a:
        setattr(b, item[0], item[1])
        b.__metadata__ = b.__metadata__
    return b


def clone(new_identifier=None):
    """Return a clone of the new component, with identifier
        new_identifier if it is not None.
        """


def is_alive(thread):
    """Helper to determine if a thread is alive (handles none safely)."""
    if not thread:
        return False
    return thread.is_alive()


def contains_definite_form(V):
    """
    Check whether a given a subspace of the 3 dimensional space (a,b,c) contains
    a definitive positive quadratic form ax^2 + 2bxy + by^2.

    TESTS::

        sage: from flatsurf.geometry.finitely_generated_matrix_group import contains_definite_form

        sage: V = ZZ**3
        sage: contains_definite_form(V.submodule([(1,1,0)]))
        True
        sage: contains_definite_form(V.submodule([(2,1,1)]))
        True
        sage: contains_definite_form(V.submodule([(1,1,1)]))
        False
        sage: contains_definite_form(V.submodule([(1,0,0),(0,1,0)]))
        True
        sage: contains_definite_form(V.submodule([(1,0,0),(0,0,1)]))
        False
        sage: contains_definite_form(V.submodule([(-1,0,0),(0,1,3)]))
        True
    """
    dim = V.dimension()
    if dim == 0:
        return False
    elif dim == 1:
        a, c, b = V.gen(0)
        return b ** 2 < a * c
    elif dim == 2:
        a1, c1, b1 = V.gen(0)
        a2, c2, b2 = V.gen(1)
        if b1 ** 2 < a1 * c1 or b2 ** 2 < a2 * c2:
            return True
        return (2 * b1 * b2 - a2 * c1 - a1 * c2) ** 2 - 4 * (b1 ** 2 - a1 * c1
            ) * (b2 ** 2 - a2 * c2) > 0
    elif dim == 3:
        return True
    else:
        raise RuntimeError


def sort_by(keys, contents, parser):
    """
    the default sort order is desc.
    :param keys: should be a list which has the index method.
    :param contents:
    :param parser:
    :return: new list
    """
    if parser.asc_key:
        index = keys.index(parser.asc_key)
        return sorted(contents, key=lambda x: x[index])
    elif parser.desc_key:
        index = keys.index(parser.desc_key)
        return sorted(contents, key=lambda x: x[index], reverse=True)
    return contents.copy()


def _is_ssl_timeout(exc):
    """ Returns True if the exception is for an SSL timeout """
    return exc.message in ('The handshake operation timed out',
        'The write operation timed out', 'The read operation timed out')


def get_geo_data_frame_from_select():
    """
    Given Lat lon and create point
    select new ST_POINT (lat, lon) as myNewPoint from table...

    Returns
    -------

    """
    return


@classmethod
def get_queryset(cls, user=None, **kwargs):
    """ Get objects queryset.

        Method is used to generate objects queryset for resource operations.
        It is aimed to:
            * Filter objects based on user. Object could be in queryset only if
            there is attribute-ForeignKey-ManyToMany path from current resource
            to current auth_user.
            * Select related objects (or prefetch them) based on requested
            requested objects to include

        NOTE: use user from parameters, it could be authenticated not with
            session, so request.user might not work

        """
    queryset = cls.Meta.model.objects
    if cls.Meta.authenticators:
        queryset = cls.update_user_queryset(queryset, user, **kwargs)
    return queryset


def check_parcel_hemi(pscalars, hemisphere):
    """
    Check hemisphere argument for package compatibility.

    Parameters
    ----------
    pscalars : numpy.ndarray
        parcels' scalar quantities
    hemisphere : 'left' or 'right' or None
        if bilateral, use None

    Returns
    -------
    'left' or 'right' or None

    Raises
    ------
    RuntimeError : pscalars is not length-360 but hemisphere not indicated
    ValueError : invalid hemisphere argument

    """
    if pscalars.size != 360 and hemisphere is None:
        raise RuntimeError(
            'you must indicate which hemisphere these pscalars correspond to')
    options = ['left', 'l', 'L', 'right', 'r', 'R', None, 'lr', 'LR']
    if hemisphere not in options:
        raise ValueError('{} is not a valid hemisphere'.format(hemisphere))
    if hemisphere in ['left', 'l', 'L']:
        return 'left'
    if hemisphere in ['right', 'r', 'R']:
        return 'right'
    if hemisphere in ['None', 'lr', 'LR']:
        return None


@classmethod
def convert_to_P1(cls, sglat):
    """
        create a P1 equivalent of the given SGLattice instance.

        Parameters
        ----------
        sglat :   SGLattice
            space group lattice instance to be converted to P1.

        Returns
        -------
        SGLattice
            instance with the same properties as sglat, however in the P1
            setting.
        """
    a, b, c, alpha, beta, gamma = (sglat.a, sglat.b, sglat.c, sglat.alpha,
        sglat.beta, sglat.gamma)
    atoms = []
    pos = []
    occ = []
    biso = []
    for at, p, o, bf in sglat.base():
        atoms.append(at)
        pos.append(('1a', p))
        occ.append(o)
        biso.append(bf)
    return cls(1, a, b, c, alpha, beta, gamma, atoms=atoms, pos=pos, occ=
        occ, b=biso)


def on_new_client_example(addr):
    """
    Example callback for new client event
    """
    print('New client: {}'.format(addr))


def store():
    """Store the news items in the DB"""


def human(n, scale):
    """ Decompose a nonnegative integer `n` into counts by unit from `scale`.

      Parameters:
      * `n`: a nonnegative integer.
      * `scale`: a sequence of `(factor,unit)` where factor is the
        size factor to the follow scale and `unit` is the designator
        of the unit.
  """
    components = []
    for factor, unit in scale:
        if factor == 0:
            components.append((n, unit))
            n = 0
            break
        remainder = n % factor
        components.append((remainder, unit))
        n //= factor
        if n == 0:
            break
    if n > 0:
        raise ValueError('invalid scale, final factor must be 0: %r' % (scale,)
            )
    return components


def revoke_db_security_group_ingress(DBSecurityGroupName=None, CIDRIP=None,
    EC2SecurityGroupName=None, EC2SecurityGroupId=None,
    EC2SecurityGroupOwnerId=None):
    """
    Revokes ingress from a DBSecurityGroup for previously authorized IP ranges or EC2 or VPC Security Groups. Required parameters for this API are one of CIDRIP, EC2SecurityGroupId for VPC, or (EC2SecurityGroupOwnerId and either EC2SecurityGroupName or EC2SecurityGroupId).
    See also: AWS API Documentation

    Examples
    This example revokes ingress for the specified CIDR block associated with the specified DB security group.
    Expected Output:

    :example: response = client.revoke_db_security_group_ingress(
        DBSecurityGroupName='string',
        CIDRIP='string',
        EC2SecurityGroupName='string',
        EC2SecurityGroupId='string',
        EC2SecurityGroupOwnerId='string'
    )

    :type DBSecurityGroupName: string
    :param DBSecurityGroupName: [REQUIRED]
            The name of the DB security group to revoke ingress from.

    :type CIDRIP: string
    :param CIDRIP: The IP range to revoke access from. Must be a valid CIDR range. If CIDRIP is specified, EC2SecurityGroupName , EC2SecurityGroupId and EC2SecurityGroupOwnerId cannot be provided.

    :type EC2SecurityGroupName: string
    :param EC2SecurityGroupName: The name of the EC2 security group to revoke access from. For VPC DB security groups, EC2SecurityGroupId must be provided. Otherwise, EC2SecurityGroupOwnerId and either EC2SecurityGroupName or EC2SecurityGroupId must be provided.

    :type EC2SecurityGroupId: string
    :param EC2SecurityGroupId: The id of the EC2 security group to revoke access from. For VPC DB security groups, EC2SecurityGroupId must be provided. Otherwise, EC2SecurityGroupOwnerId and either EC2SecurityGroupName or EC2SecurityGroupId must be provided.

    :type EC2SecurityGroupOwnerId: string
    :param EC2SecurityGroupOwnerId: The AWS Account Number of the owner of the EC2 security group specified in the EC2SecurityGroupName parameter. The AWS Access Key ID is not an acceptable value. For VPC DB security groups, EC2SecurityGroupId must be provided. Otherwise, EC2SecurityGroupOwnerId and either EC2SecurityGroupName or EC2SecurityGroupId must be provided.

    :rtype: dict
    :return: {
        'DBSecurityGroup': {
            'OwnerId': 'string',
            'DBSecurityGroupName': 'string',
            'DBSecurityGroupDescription': 'string',
            'VpcId': 'string',
            'EC2SecurityGroups': [
                {
                    'Status': 'string',
                    'EC2SecurityGroupName': 'string',
                    'EC2SecurityGroupId': 'string',
                    'EC2SecurityGroupOwnerId': 'string'
                },
            ],
            'IPRanges': [
                {
                    'Status': 'string',
                    'CIDRIP': 'string'
                },
            ],
            'DBSecurityGroupArn': 'string'
        }
    }

    :returns:
    DescribeDBSecurityGroups
    AuthorizeDBSecurityGroupIngress
    CreateDBSecurityGroup
    RevokeDBSecurityGroupIngress

    """
    pass


@classmethod
def filter_by(cls, **kwargs):
    """Фильтр с упрощенным синтаксисом."""
    return cls.query().filter_by(**kwargs)


def date_handler(obj):
    """ format dates to ISO format """
    return obj.isoformat() if hasattr(obj, 'isoformat') else obj


def estimate_kaiser_bessel_beta(W):
    """
    Estimate the kaiser bessel beta using the following heuristic:

    .. math::

        \\beta = 2.34 \\times W

    Derived from `Nonuniform fast Fourier transforms
    using min-max interpolation
    <nufft-min-max-ref_>`_.

    .. _nufft-min-max-ref: https://ieeexplore.ieee.org/document/1166689/

    Parameters
    ----------
    W : int
        Width of the filter

    Returns
    -------
    float
        Kaiser Bessel beta shape parameter
    """
    return 2.34 * W


def is_list_of_ints(intlist):
    """ Return True if list is a list of ints. """
    if not isinstance(intlist, list):
        return False
    for i in intlist:
        if not isinstance(i, int):
            return False
    return True


def _int_xor(i1, i2):
    """Return True if one and only one of i1 and i2 is zero."""
    return (i1 or i2) and not (i1 and i2)


def jacardCoefficient(a, b):
    """Return the Jacard coefficient of a and b.

    The jacard coefficient is defined as the overlap between two sets: the sum
    of all equal elements divided by the size of the sets.

    Mind that a and b must b in Hamming space, so every element must either be
    1 or 0.
    """
    if a.shape != b.shape:
        raise ValueError('Arrays must be of same shape')
    length = a.shape[0]
    a = a.astype(bool)
    b = b.astype(bool)
    return float((a == b).sum()) / length


def ensure_sequence(element):
    """Ensure the given argument is a sequence object (tuple, list). If not, return a list containing its value."""
    return element if isinstance(element, (tuple, list)) else [element]


@classmethod
def items(cls):
    """
        All values for this enum
        :return: list of tuples

        """
    return [cls.PRECIPITATION, cls.WIND, cls.TEMPERATURE, cls.PRESSURE]


def _convert_counts_logits_to_mean_disp(total_count, logits):
    """NB parameterizations conversion

        :param total_count: Number of failures until the experiment is stopped.
        :param logits: success logits.
        :return: the mean and inverse overdispersion of the NB distribution.
    """
    theta = total_count
    mu = logits.exp() * theta
    return mu, theta


def total_seconds(table):
    """Returns total amount of seconds in a given table."""
    seconds = 0
    for row in table:
        seconds += row[2]
    return seconds


@classmethod
def purchase_twilio_number(cls, user_owner, phone_number):
    """
        Wrapper method of twilio.incoming_phone_numbers.create(phone_number).
        This allows to purchase twilio numbers. Returns a TwilioNumber Instance.
        """
    api = cls.twilio_api()
    tw_number = api.incoming_phone_numbers.create(phone_number=phone_number)
    new_twilio_number, created = cls.objects.get_or_create(twilio_number=
        tw_number.phone_number, defaults={'user': user_owner})
    new_twilio_number.twilio_number_sid = tw_number.sid
    new_twilio_number.sms_enabled = tw_number.capabilities['sms']
    new_twilio_number.mms_enabled = tw_number.capabilities['mms']
    new_twilio_number.voice_enabled = tw_number.capabilities['voice']
    new_twilio_number.friendly_name = tw_number.friendly_name
    new_twilio_number.save()
    new_twilio_number.update_twilio_urls_to_default()
    return new_twilio_number


@staticmethod
def get_option(options, option_name, profile, region):
    """Get an option from more precise to more general."""
    result = options
    if isinstance(result, str):
        return result
    result = options.get(profile, {}).get(region, {})
    if isinstance(result, dict):
        result = result.get(option_name)
    if isinstance(result, str):
        return result
    result = options.get(profile, {})
    if isinstance(result, dict):
        result = result.get(option_name)
    if isinstance(result, str):
        return result
    result = options.get(region, {})
    if isinstance(result, dict):
        result = result.get(option_name)
    if isinstance(result, str):
        return result
    result = options
    if isinstance(result, dict):
        result = result.get(option_name)
    return None


def suffix_kwd(name):
    """Add an underscore suffix if name if a Python keyword."""
    from keyword import iskeyword
    return '{}_'.format(name) if iskeyword(name) else name


@staticmethod
def any_events(events, count):
    """Use as ``evaluate`` to test that any events have triggered"""
    return count or not events


def plot_coords(ax, ob):
    """Plot coordinates of shapely objects

    Parameters
    ----------
    ax : ``matplotlib.pyplot.Axes`` object
        Axes for plotting
    ob : ``Shapely`` object
        Geometry object whose x,y coordinates should be plotted

    """
    try:
        x, y = ob.xy
        ax.plot(x, y, 'o', color='#999999', zorder=1)
    except NotImplementedError:
        for line in ob:
            x, y = line.xy
            ax.plot(x, y, 'o', color='#999999', zorder=1)


def findTypeName(name, typ, body):
    """ Return the the portal type (an ID) for a PUT request.

        o 'name' is the filename supplied as the end of the path of the
          PUT request.

        o 'typ' is the MIME type for the request (which may have been guessed
          already from the extension or the body).

        o 'body' is the actual payload of the PUT request.

        o Return None if no match found.
        """


def _label_tuple_to_text(label, diff, genes=None):
    """
    Converts the variant label tuple to a string.

    Parameters
    ----------
    label : tuple(str)
        A tuple of (chrom, pos, ref, alt).
    diff : float
        The max difference score across some or all features in the model.
    genes : list(str) or None, optional
        Default is None. If the closest protein-coding `genes` are specified,
        will display them in the label text.

    Returns
    -------
    str
        The label text.

    """
    chrom, pos, ref, alt = label
    if genes is not None:
        if len(genes) == 0:
            genes_str = 'none found'
        else:
            genes_str = ', '.join(genes)
        text = (
            'max diff score: {0}
{1} {2}, {3}/{4}
closest protein-coding gene(s): {5}'
            .format(diff, chrom, pos, ref, alt, genes_str))
    else:
        text = 'max diff score: {0}
{1} {2}, {3}/{4}'.format(diff,
            chrom, pos, ref, alt)
    return text


def get_ip_profile(active_connection):
    """
    Get NMSettingIP6Config from NMActiveConnection.
    For any error, return None.
    """
    remote_conn = active_connection.get_connection()
    if remote_conn:
        return remote_conn.get_setting_ip6_config()
    return None


def p_track_flag_no_copy(t):
    """track_flag : NO COPY"""
    from audiotools.toc import TOCFlag_COPY
    t[0] = TOCFlag_COPY(False)


def p_type_map(p):
    """type : MAP type type"""
    p[0] = ['map', [p[2], p[3]]]


def _log_format(y, pos):
    """
    Needed to move log values by one, so first increment, then decrement
    """
    return y


@staticmethod
def do_null(parent=None, ident=0):
    """
        Handles a TC_NULL opcode

        :param parent:
        :param ident: Log indentation level
        :return: Always None
        """
    return None


def run_on_exec(script):
    """Compile and Exec sccrip.

    Parameters
    ----------
    script : str
        Python script to be executed.

    """
    compiled = compile(script + '\n', '<string>', 'exec')
    exec(compiled, locals(), locals())


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

        :param GroupRenameDetails val:
        :rtype: EventDetails
        """
    return cls('group_rename_details', val)


@classmethod
def generate_custom_ridge(cls, rfr_args):
    """Generates a custom decision tree wrapper.
        :param rfr_args: parameters to pass into the decision tree
        :type rfr_args: dict
        :rtype: cls
        """
    return type('Custom' + cls.__name__, (cls,), dict(rfr_args=rfr_args))


@classmethod
def new(cls, string=None):
    """
        Creates a new hashing object and returns it. The optional
        **string** parameter, if supplied, will be immediately
        hashed into the object's starting state, as if
        obj.update(string) was called.
        """
    return cls(string)


def get_generic_type(obj):
    """Get the generic type of an object if possible, or runtime class otherwise.
    Examples::
        class Node(Generic[T]):
            ...
        type(Node[int]()) == Node
        get_generic_type(Node[int]()) == Node[int]
        get_generic_type(Node[T]()) == Node[T]
        get_generic_type(1) == int
    """
    gen_type = getattr(obj, '__orig_class__', None)
    return gen_type if gen_type is not None else type(obj)


@staticmethod
def numerize(item):
    """Converts an item to a numeric value. Falls back to strings.

        >>> Parser.numerize(3)
        3
        >>> Parser.numerize("  3   ")
        3
        >>> Parser.numerize("55.57")
        55.57
        >>> Parser.numerize("Million")
        'Million'
        """
    try:
        return int(item)
    except ValueError:
        try:
            return float(item)
        except ValueError:
            return item


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


@classmethod
def get_tires_wheels_list(cls):
    """
        Method for fetching info about tires and wheels (if cargo is "tires-wheels").

        :example:
            ``Common.get_tires_wheels_list()``
        :return:
            dictionary with info about tires and wheels
        :rtype:
            dict
        """
    req = cls.send(method='getTiresWheelsList')
    return req