def group_data(data, groupby_column_name, use_mean=None):
    """
    Group data by scenario

    Parameters
    ----------
    data: DataFrame
        Data
    groupby_column_name: strings
        Name of data column which contains scenario numbers
    use_mean: list of column names or None, optional
        Name of data columns which should be reduced to a single value per
        scenario by taking the mean

    Returns
    ----------
    grouped_data: list of dictionaries
        Grouped data
    """
    grouped_data = []
    for exp_num, group in data.groupby(data[groupby_column_name]):
        d = {}
        for col in group.columns:
            if col in use_mean:
                d[col] = group[col].mean()
            else:
                d[col] = list(group[col])
        grouped_data.append(d)
    return grouped_data


def find_lcs(x, y):
    """Find longest common subsequence."""
    m, n = len(x), len(y)
    C = [([0] * (n + 1)) for _ in range(m + 1)]
    for i in range(1, m + 1):
        for j in range(1, n + 1):
            C[i][j] = C[i - 1][j - 1] + 1 if x[i - 1] == y[j - 1] else max(C
                [i][j - 1], C[i - 1][j])
    index = C[m][n]
    lcs = [None] * index
    while m > 0 and n > 0:
        if x[m - 1] == y[n - 1]:
            lcs[index - 1] = x[m - 1]
            m, n, index = m - 1, n - 1, index - 1
        elif C[m - 1][n] > C[m][n - 1]:
            m -= 1
        else:
            n -= 1
    return lcs


def loadbalancer_not_found():
    """
    Verified 2015-06-16:
    - when trying to update a CLB node on a CLB that doesn't exist

    :return: a `tuple` of (dict body message, 404 http status code)
    """
    return {'message': 'Load balancer not found', 'code': 404}, 404


def split_filename(filename):
    """
    Received a standard style rpm fullname and returns
    name, version, release, epoch, arch
    Example: foo-1.0-1.i386.rpm returns foo, 1.0, 1, i386
             1:bar-9-123a.ia64.rpm returns bar, 9, 123a, 1, ia64

    This function replaces rpmUtils.miscutils.splitFilename, see
    https://bugzilla.redhat.com/1452801
    """
    if filename.endswith('.rpm'):
        filename = filename.split('.rpm')[0]
    components = filename.split(':')
    if len(components) > 1:
        epoch = components[0]
    else:
        epoch = ''
    arch = filename.rsplit('.')[-1]
    remaining = filename.rsplit('.%s' % arch)[0]
    release = remaining.rsplit('-')[-1]
    version = remaining.rsplit('-')[-2]
    name = '-'.join(remaining.rsplit('-')[:-2])
    return name, version, release, epoch, arch


def undo_history(item: int=0):
    """Redo specific action in history

    :param item: Item
    :type item: int
    """
    pass


def set_default_if_none(arg, n, attr):
    """
    Set any argument to an attribute of n if None
    """
    return sorted(getattr(n, attr)) if arg is None else sorted(arg)


def delta_p(H, D):
    """ Displacement at Pu
    """
    return min(0.04 * (H + D / 2), 0.1 * D)


def _addCACertsToContext(context):
    """
        Add certificate-authority certificates to an SSL context whose
        connections should trust those authorities.

        @param context: An SSL context for a connection which should be
            verified by some certificate authority.
        @type context: L{OpenSSL.SSL.Context}

        @return: L{None}
        """


@classmethod
def verify_bis_signature(cls, signature: str, public_key: str, buffer:
    bytes, address: str) ->None:
    """Verify signature from bismuth tx network format"""
    verifier = cls.address_to_signer(address)
    verifier.verify_bis_signature(signature, public_key, buffer, address)


def freestyle_modifier_copy():
    """Duplicate the modifier within the list of modifiers

    """
    pass


def RGB(red, green, blue):
    """
    Given integer values of Red, Green, Blue, return a color string "#RRGGBB"
    :param red: (int) Red portion from 0 to 255
    :param green: (int) Green portion from 0 to 255
    :param  blue: (int) Blue portion from 0 to 255
    :return: (str) A single RGB String in the format "#RRGGBB" where each pair is a hex number.
    """
    return '#%02x%02x%02x' % (red, green, blue)


def checkCoulombPair(parameters, group1, group2, distance):
    """
    Checks if this Coulomb interaction should be done - a propka2.0 hack
    """
    Npair = group1.Nmass + group2.Nmass
    do_coulomb = True
    if not (group1.titratable and group2.titratable):
        do_coulomb = False
    if distance > parameters.coulomb_cutoff2:
        do_coulomb = False
    if Npair < parameters.Nmin:
        do_coulomb = False
    return do_coulomb


def import_subscribers(subscribers):
    """ Import mailing list subscribers """


def history_append(text: str='', current_character: int=0,
    remove_duplicates: bool=False):
    """Append history at cursor position

    :param text: Text, Text to insert at the cursor position
    :type text: str
    :param current_character: Cursor, The index of the cursor
    :type current_character: int
    :param remove_duplicates: Remove Duplicates, Remove duplicate items in the history
    :type remove_duplicates: bool
    """
    pass


@staticmethod
def _import_type(line):
    """If the current line is an import line it will return its type (from or straight)"""
    if 'isort:skip' in line:
        return
    elif line.startswith('import '):
        return 'straight'
    elif line.startswith('from '):
        return 'from'


def convert_file_for_api(filemd):
    """
    Creates a new dictionary that contains only the values that are needed
    for the upload with the correct keys (Taken from `uploadclient.py`)

    :param file: dictionary describing a file to upload

    :returns: dictionary containing not more then the needed values for the
    upload
    """
    replica = {}
    replica['scope'] = filemd['did_scope']
    replica['name'] = filemd['did_name']
    replica['bytes'] = filemd['bytes']
    replica['adler32'] = filemd['adler32']
    replica['md5'] = filemd['md5']
    replica['meta'] = filemd['meta']
    replica['state'] = filemd['state']
    pfn = filemd.get('pfn')
    if pfn:
        replica['pfn'] = pfn
    return replica


def read_len_byte(lb):
    """parses the length byte and returns the sizes of the next twofields
    :param lb: int/byte
    :returns tuple
    """
    return lb >> 4, lb & 15


def parse_column_type(s, l, t):
    """
    int or "mytype" or varchar(255)
    """
    result = t['name']
    args = t.get('args')
    result += '(' + args + ')' if args else ''
    return result


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


def dbTables():
    """
  db tables to init
  """
    return [{'name': 'bot', 'schemas': [{'name': 'id', 'type': 'string',
        'primary': True}, {'name': 'token', 'type': 'json'}, {'name':
        'data', 'type': 'json'}]}, {'name': 'user', 'schemas': [{'name':
        'id', 'type': 'string', 'primary': True}, {'name': 'token', 'type':
        'json'}, {'name': 'groups', 'type': 'json'}, {'name': 'data',
        'type': 'json'}]}]


def httpdate(dt):
    """Return a string representation of a date according to RFC 1123
    (HTTP/1.1).

    The supplied date must be in UTC.
    """
    weekday = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'][dt.weekday()]
    month = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
        'Oct', 'Nov', 'Dec'][dt.month - 1]
    return '%s, %02d %s %04d %02d:%02d:%02d GMT' % (weekday, dt.day, month,
        dt.year, dt.hour, dt.minute, dt.second)


def replaceDingbat(u_match):
    """
	u_match: instance of _sre.SRE_Match
	replace chars \\u008c-\\u0095 with \\u2776-\\u277f
	"""
    ch = u_match.group(0)
    code = ch + (10102 - 140)
    return chr(code)


def _collapse0(a):
    """Collapse all dimensions of `a` except the first.
    """
    return a.reshape(a.shape[0], -1)


def internal_attr(s):
    """
    Checks whether this attribute name is reserved for internal use
    """
    return s.startswith('__')


def modifyRequest(req, resp):
    """Copies cookie-supplied credentials to the basic auth fields.

        Returns a flag indicating what the user is trying to do with
        cookies: ATTEMPT_NONE, ATTEMPT_LOGIN, or ATTEMPT_RESUME.  If
        cookie login is disabled for this request, raises
        CookieCrumblerDisabled.
        """


def get_repo_from_tool(tool):
    """
    Get the minimum items required for re-installing a (list of) tools
    """
    if not tool.get('tool_shed_repository', None):
        return {}
    tsr = tool['tool_shed_repository']
    repo = {'name': tsr['name'], 'owner': tsr['owner'], 'tool_shed_url':
        tsr['tool_shed'], 'revisions': [tsr['changeset_revision']],
        'tool_panel_section_id': tool['panel_section_id'],
        'tool_panel_section_label': tool['panel_section_name']}
    return repo


def red_b(string):
    """background color to red"""
    return '\x1b[41m' + string + '\x1b[0m'


def number2powers(n):
    """
    Converts an integer value to list of powers of 2.
    :param n: integer value to convert
    :type n: int
    :return: list of powers of 2
    """
    s = 1
    while n >= s:
        if n & s:
            yield s
        s <<= 1


def bool_encode(d):
    """ Encodes a boolean. """
    return d and '1' or '0'


def start_via(gateway, hostport=None):
    """ return a host, port tuple,
        after instanciating a socketserver on the given gateway
    """
    if hostport is None:
        host, port = 'localhost', 0
    else:
        host, port = hostport
    from execnet.script import socketserver
    channel = gateway.remote_exec(socketserver)
    channel.send((host, port))
    realhost, realport = channel.receive()
    if not realhost or realhost == '0.0.0.0':
        realhost = 'localhost'
    return realhost, realport


def subparser(subparsers):
    """Define the `kevlar augment` command-line interface."""
    desc = """    Internally, kevlar annotates sequences with "interesting k-mers" and uses
    "augmented" Fastq and Fasta formats. Processing sequences with third-part
    tools usually requires discarding these annotations. This command is used
    to augment/reaugment a set of sequences using annotations from an already
    augmented sequence file.
    """
    subparser = subparsers.add_parser('augment', description=desc)
    subparser.add_argument('-o', '--out', metavar='FILE', help=
        'output file; default is terminal (stdout)')
    subparser.add_argument('augseqs', help='augmented sequence file')
    subparser.add_argument('seqs', help='sequences to annotate')


def non_condition(*args, **kwargs):
    """A condition function for the announce- or notify condition of an input
    connector, if that condition is not specified.

    :returns: True
    """
    return True


def remove_slug(path):
    """
    Return the remainin part of the path

        >>> remove_slug('/test/some/function/')
        test/some
    """
    if path.endswith('/'):
        path = path[:-1]
    if path.startswith('/'):
        path = path[1:]
    if '/' not in path or not path:
        return None
    parts = path.split('/')[:-1]
    return '/'.join(parts)


def names(zelf, *args, **kwargs):
    """ skip the unwanted keys e.g those that start with a "_". """
    for key in zelf.keys():
        k = str(key)
        if k.startswith('_'):
            continue
        yield key


def safe_enumerate(iterable):
    """Enumerate which does not yield None values"""
    for i, v in enumerate(iterable):
        if v is not None:
            yield i, v


def update(c):
    """
    Perform an ``apt-get update`` operation.
    """
    c.sudo('apt-get update')


@classmethod
def hmac_sha256(cls, key):
    """Creates a new HMAC SHA256 algorithm instance.

        Args:
            key: Signer key as a byte sequence.

        Returns:
            UserImportHash: A new ``UserImportHash``.
        """
    return cls._hmac('HMAC_SHA256', key)


def format_file(source, target, **kwargs):
    """Format Input File."""
    with open(target, 'w') as target_file:
        with open(source, 'r') as source_file:
            for line in source_file:
                try:
                    target_file.write(line.format(**kwargs))
                except KeyError:
                    target_file.write(line)


def convert_query_to_sql_statement(query):
    """
    Convert a Query object created from orm query, into executable sql statement.

    :param query: :class:`sqlalchemy.orm.Query`

    :return: :class:`sqlalchemy.sql.selectable.Select`
    """
    context = query._compile_context()
    context.statement.use_labels = False
    return context.statement


@classmethod
def from_cache(cls, cache, *, session=None, always_cache=False):
    """Make Sequence Factory from Pre-loaded Cache."""
    return cls(factory=lambda : cache, session=session, always_cache=
        always_cache)


def float_to_str(value: float) ->str:
    """Converts double number to string using {.12g} formatter."""
    return format(value, '.12g')


def register_activity_type(domain=None, name=None, version=None,
    description=None, defaultTaskStartToCloseTimeout=None,
    defaultTaskHeartbeatTimeout=None, defaultTaskList=None,
    defaultTaskPriority=None, defaultTaskScheduleToStartTimeout=None,
    defaultTaskScheduleToCloseTimeout=None):
    """
    Registers a new activity type along with its configuration settings in the specified domain.
    Access Control
    You can use IAM policies to control this action's access to Amazon SWF resources as follows:
    If the caller does not have sufficient permissions to invoke the action, or the parameter values fall outside the specified constraints, the action fails. The associated event attribute's cause parameter will be set to OPERATION_NOT_PERMITTED. For details and example IAM policies, see Using IAM to Manage Access to Amazon SWF Workflows .
    See also: AWS API Documentation

    :example: response = client.register_activity_type(
        domain='string',
        name='string',
        version='string',
        description='string',
        defaultTaskStartToCloseTimeout='string',
        defaultTaskHeartbeatTimeout='string',
        defaultTaskList={
            'name': 'string'
        },
        defaultTaskPriority='string',
        defaultTaskScheduleToStartTimeout='string',
        defaultTaskScheduleToCloseTimeout='string'
    )

    :type domain: string
    :param domain: [REQUIRED]
            The name of the domain in which this activity is to be registered.

    :type name: string
    :param name: [REQUIRED]
            The name of the activity type within the domain.
            The specified string must not start or end with whitespace. It must not contain a : (colon), / (slash), | (vertical bar), or any control characters (u0000-u001f | u007f - u009f). Also, it must not contain the literal string quotarnquot.

    :type version: string
    :param version: [REQUIRED]
            The version of the activity type.
            Note
            The activity type consists of the name and version, the combination of which must be unique within the domain.
            The specified string must not start or end with whitespace. It must not contain a : (colon), / (slash), | (vertical bar), or any control characters (u0000-u001f | u007f - u009f). Also, it must not contain the literal string quotarnquot.

    :type description: string
    :param description: A textual description of the activity type.

    :type defaultTaskStartToCloseTimeout: string
    :param defaultTaskStartToCloseTimeout: If set, specifies the default maximum duration that a worker can take to process tasks of this activity type. This default can be overridden when scheduling an activity task using the ScheduleActivityTask decision.
            The duration is specified in seconds; an integer greater than or equal to 0. The value 'NONE' can be used to specify unlimited duration.

    :type defaultTaskHeartbeatTimeout: string
    :param defaultTaskHeartbeatTimeout: If set, specifies the default maximum time before which a worker processing a task of this type must report progress by calling RecordActivityTaskHeartbeat . If the timeout is exceeded, the activity task is automatically timed out. This default can be overridden when scheduling an activity task using the ScheduleActivityTask decision. If the activity worker subsequently attempts to record a heartbeat or returns a result, the activity worker receives an UnknownResource fault. In this case, Amazon SWF no longer considers the activity task to be valid; the activity worker should clean up the activity task.
            The duration is specified in seconds; an integer greater than or equal to 0. The value 'NONE' can be used to specify unlimited duration.

    :type defaultTaskList: dict
    :param defaultTaskList: If set, specifies the default task list to use for scheduling tasks of this activity type. This default task list is used if a task list is not provided when a task is scheduled through the ScheduleActivityTask decision.
            name (string) -- [REQUIRED]The name of the task list.

    :type defaultTaskPriority: string
    :param defaultTaskPriority: The default task priority to assign to the activity type. If not assigned, then '0' will be used. Valid values are integers that range from Java's Integer.MIN_VALUE (-2147483648) to Integer.MAX_VALUE (2147483647). Higher numbers indicate higher priority.
            For more information about setting task priority, see Setting Task Priority in the Amazon Simple Workflow Developer Guide .

    :type defaultTaskScheduleToStartTimeout: string
    :param defaultTaskScheduleToStartTimeout: If set, specifies the default maximum duration that a task of this activity type can wait before being assigned to a worker. This default can be overridden when scheduling an activity task using the ScheduleActivityTask decision.
            The duration is specified in seconds; an integer greater than or equal to 0. The value 'NONE' can be used to specify unlimited duration.

    :type defaultTaskScheduleToCloseTimeout: string
    :param defaultTaskScheduleToCloseTimeout: If set, specifies the default maximum duration for a task of this activity type. This default can be overridden when scheduling an activity task using the ScheduleActivityTask decision.
            The duration is specified in seconds; an integer greater than or equal to 0. The value 'NONE' can be used to specify unlimited duration.

    :returns:
    domain (string) -- [REQUIRED]
    The name of the domain in which this activity is to be registered.

    name (string) -- [REQUIRED]
    The name of the activity type within the domain.
    The specified string must not start or end with whitespace. It must not contain a : (colon), / (slash), | (vertical bar), or any control characters (u0000-u001f | u007f - u009f). Also, it must not contain the literal string quotarnquot.

    version (string) -- [REQUIRED]
    The version of the activity type.

    Note
    The activity type consists of the name and version, the combination of which must be unique within the domain.

    The specified string must not start or end with whitespace. It must not contain a : (colon), / (slash), | (vertical bar), or any control characters (u0000-u001f | u007f - u009f). Also, it must not contain the literal string quotarnquot.

    description (string) -- A textual description of the activity type.
    defaultTaskStartToCloseTimeout (string) -- If set, specifies the default maximum duration that a worker can take to process tasks of this activity type. This default can be overridden when scheduling an activity task using the ScheduleActivityTask decision.
    The duration is specified in seconds; an integer greater than or equal to 0. The value "NONE" can be used to specify unlimited duration.

    defaultTaskHeartbeatTimeout (string) -- If set, specifies the default maximum time before which a worker processing a task of this type must report progress by calling  RecordActivityTaskHeartbeat . If the timeout is exceeded, the activity task is automatically timed out. This default can be overridden when scheduling an activity task using the ScheduleActivityTask decision. If the activity worker subsequently attempts to record a heartbeat or returns a result, the activity worker receives an UnknownResource fault. In this case, Amazon SWF no longer considers the activity task to be valid; the activity worker should clean up the activity task.
    The duration is specified in seconds; an integer greater than or equal to 0. The value "NONE" can be used to specify unlimited duration.

    defaultTaskList (dict) -- If set, specifies the default task list to use for scheduling tasks of this activity type. This default task list is used if a task list is not provided when a task is scheduled through the ScheduleActivityTask decision.

    name (string) -- [REQUIRED]The name of the task list.

    defaultTaskPriority (string) -- The default task priority to assign to the activity type. If not assigned, then "0" will be used. Valid values are integers that range from Java's Integer.MIN_VALUE (-2147483648) to Integer.MAX_VALUE (2147483647). Higher numbers indicate higher priority.
    For more information about setting task priority, see Setting Task Priority in the Amazon Simple Workflow Developer Guide .

    defaultTaskScheduleToStartTimeout (string) -- If set, specifies the default maximum duration that a task of this activity type can wait before being assigned to a worker. This default can be overridden when scheduling an activity task using the ScheduleActivityTask decision.
    The duration is specified in seconds; an integer greater than or equal to 0. The value "NONE" can be used to specify unlimited duration.

    defaultTaskScheduleToCloseTimeout (string) -- If set, specifies the default maximum duration for a task of this activity type. This default can be overridden when scheduling an activity task using the ScheduleActivityTask decision.
    The duration is specified in seconds; an integer greater than or equal to 0. The value "NONE" can be used to specify unlimited duration.

    """
    pass


@classmethod
def is_prop_required(cls, name: str) ->bool:
    """Tell if the prop defined by `name` is a required one.

        Parameters
        ----------
        name : str
            The name of the prop we want to know if it is required.

        Returns
        -------
        bool
            ``True`` if the prop is required, ``False`` otherwise.

        Raises
        ------
        InvalidPropNameError
            If there is no prop with the given `name`.

        Examples
        --------
        >>> class Greeting(Element):
        ...     class PropTypes:
        ...         name: str = "World"
        ...         surname: Required[str]

        >>> Greeting.is_prop_required("name")
        False
        >>> Greeting.is_prop_required("surname")
        True
        >>> Greeting.is_prop_required("firstname")
        Traceback (most recent call last):
        ...
        mixt.exceptions.InvalidPropNameError: <Greeting>.firstname: is not an allowed prop

        """
    return cls.PropTypes.__is_required__(cls.prop_name(name))


def psi_H_K_Cl_PK74(T, P):
    """c-c'-a: hydrogen potassium chloride [PK74]."""
    psi = -0.007
    valid = T == 298.15
    return psi, valid


def ensure_dashes(opts):
    """Ensure that the options have the right number of dashes."""
    for opt in opts:
        if opt.startswith('-'):
            yield opt
        else:
            yield '-' * (1 + 1 * (len(opt) > 1)) + opt


def range_split(hosts):
    """
    Split up a range string, this needs to separate comma separated
    items unless they are within square brackets and split out set operations
    as separate items.
    """
    in_brackets = False
    current = ''
    result_list = []
    for c in hosts:
        if c in ['[']:
            in_brackets = True
        if c in [']']:
            in_brackets = False
        if not in_brackets and c == ',':
            result_list.append(current)
            current = ''
        elif not in_brackets and c in [','] and len(current) == 0:
            pass
        else:
            current += c
    current = current.strip().strip(',')
    if current:
        result_list.append(current)
    return result_list


def is_network_appbase_ready(props):
    """Checks if the network is appbase ready"""
    if 'STEEMIT_BLOCKCHAIN_VERSION' in props:
        return False
    elif 'STEEM_BLOCKCHAIN_VERSION' in props:
        return True
    elif 'HIVE_BLOCKCHAIN_VERSION' in props:
        return True
    else:
        return False


def bond_is_conjugated(bond):
    """Get whether the bond is conjugated.
    Parameters
    ----------
    bond : rdkit.Chem.rdchem.Bond
        RDKit bond instance.
    Returns
    -------
    list
        List containing one bool only.
    """
    return [bond.GetIsConjugated()]


def combine(path1, path2):
    """Join two paths together.

    This is faster than :func:`~fs.path.join`, but only works when the
    second path is relative, and there are no back references in either
    path.

    Arguments:
        path1 (str): A PyFilesytem path.
        path2 (str): A PyFilesytem path.

    Returns:
        str: The joint path.

    Example:
        >>> combine("foo/bar", "baz")
        'foo/bar/baz'

    """
    if not path1:
        return path2.lstrip()
    return '{}/{}'.format(path1.rstrip('/'), path2.lstrip('/'))


def parse_patterns(patterns_spec, ignore_patterns_spec, separator=';'):
    """
  Parses pattern argument specs and returns a two-tuple of
  (patterns, ignore_patterns).
  """
    patterns = patterns_spec.split(separator)
    ignore_patterns = ignore_patterns_spec.split(separator)
    if ignore_patterns == ['']:
        ignore_patterns = []
    return patterns, ignore_patterns


def ensure_num_chosen_alts_equals_num_obs(obs_id_col, choice_col, df):
    """
    Checks that the total number of recorded choices equals the total number of
    observations. If this is not the case, raise helpful ValueError messages.

    Parameters
    ----------
    obs_id_col : str.
        Denotes the column in `df` that contains the observation ID values for
        each row.
    choice_col : str.
        Denotes the column in `long_data` that contains a one if the
        alternative pertaining to the given row was the observed outcome for
        the observation pertaining to the given row and a zero otherwise.
    df : pandas dataframe.
        The dataframe whose choices and observations will be checked.

    Returns
    -------
    None.
    """
    num_obs = df[obs_id_col].unique().shape[0]
    num_choices = df[choice_col].sum()
    if num_choices < num_obs:
        msg = 'One or more observations have not chosen one '
        msg_2 = 'of the alternatives available to him/her'
        raise ValueError(msg + msg_2)
    if num_choices > num_obs:
        msg = 'One or more observations has chosen multiple alternatives'
        raise ValueError(msg)
    return 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 '+'


def unsqueeze(data, axis, oldshape):
    """
    Unsqueeze a collapsed array

    >>> from numpy import mean
    >>> from numpy.random import standard_normal
    >>> x = standard_normal((3,4,5))
    >>> m = mean(x, axis=1)
    >>> m.shape
    (3, 5)
    >>> m = unsqueeze(m, 1, x.shape)
    >>> m.shape
    (3, 1, 5)
    >>>
    """
    newshape = list(oldshape)
    newshape[axis] = 1
    return data.reshape(newshape)


def unindex_resource(resource_or_oid, action_mode=None):
    """Deregister the resource in indexes of this catalog using objectid or
        resource ``resource_or_oid``.  If ``resource_or_oid`` is an integer, it
        will be used as the oid; if ``resource_or_oid`` is a resource, its
        ``__oid__`` attribute will be used as the oid.  ``action_mode``, if
        supplied, should be one of ``None``,
        :attr:`~substanced.interfaces.MODE_IMMEDIATE`,
        :attr:`~substanced.interfaces.MODE_ATCOMMIT` or
        :attr:`~substanced.interfaces.MODE_DEFERRED`."""


def list_grants(Limit=None, Marker=None, KeyId=None):
    """
    List the grants for a specified key.
    See also: AWS API Documentation

    Examples
    The following example lists grants for the specified CMK.
    Expected Output:

    :example: response = client.list_grants(
        Limit=123,
        Marker='string',
        KeyId='string'
    )

    :type Limit: integer
    :param Limit: Use this parameter to specify the maximum number of items to return. When this value is present, AWS KMS does not return more than the specified number of items, but it might return fewer.
            This value is optional. If you include a value, it must be between 1 and 100, inclusive. If you do not include a value, it defaults to 50.

    :type Marker: string
    :param Marker: Use this parameter in a subsequent request after you receive a response with truncated results. Set it to the value of NextMarker from the truncated response you just received.

    :type KeyId: string
    :param KeyId: [REQUIRED]
            A unique identifier for the customer master key. This value can be a globally unique identifier or the fully specified ARN to a key.
            Key ARN Example - arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012
            Globally Unique Key ID Example - 12345678-1234-1234-1234-123456789012

    :rtype: dict
    :return: {
        'Grants': [
            {
                'KeyId': 'string',
                'GrantId': 'string',
                'Name': 'string',
                'CreationDate': datetime(2015, 1, 1),
                'GranteePrincipal': 'string',
                'RetiringPrincipal': 'string',
                'IssuingAccount': 'string',
                'Operations': [
                    'Decrypt'|'Encrypt'|'GenerateDataKey'|'GenerateDataKeyWithoutPlaintext'|'ReEncryptFrom'|'ReEncryptTo'|'CreateGrant'|'RetireGrant'|'DescribeKey',
                ],
                'Constraints': {
                    'EncryptionContextSubset': {
                        'string': 'string'
                    },
                    'EncryptionContextEquals': {
                        'string': 'string'
                    }
                }
            },
        ],
        'NextMarker': 'string',
        'Truncated': True|False
    }

    :returns:
    (string) --

    """
    pass


@staticmethod
def _escape_value(value) ->str:
    """
        Formats and replaces backslashes and single quoted parenthesis
        :param value: str
        :return: str
        """
    if isinstance(value, str):
        return '{}'.format(value.replace('\\', '\\\\').replace('"', '\\"').
            replace('(', '\\(').replace(')', '\\)'))
    else:
        return value


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 __call__():
    """ Renders the calendar
        """


def process_exit_code(retval):
    """Process a waitpid returned exit code.

    :return: The exit code if it exit'd, the signal if it died from signalling.
    """
    if retval & 255:
        return (retval & 255) << 8
    return retval >> 8


def default_features_factories():
    """These are the default features used by the :class:`.CRFSlotFiller`
        objects"""
    from snips_nlu.slot_filler.crf_utils import TaggingScheme
    from snips_nlu.slot_filler.feature_factory import NgramFactory, IsDigitFactory, IsFirstFactory, IsLastFactory, ShapeNgramFactory, CustomEntityMatchFactory, BuiltinEntityMatchFactory
    return [{'args': {'common_words_gazetteer_name': None, 'use_stemming':
        False, 'n': 1}, 'factory_name': NgramFactory.name, 'offsets': [-2,
        -1, 0, 1, 2]}, {'args': {'common_words_gazetteer_name': None,
        'use_stemming': False, 'n': 2}, 'factory_name': NgramFactory.name,
        'offsets': [-2, 1]}, {'args': {}, 'factory_name': IsDigitFactory.
        name, 'offsets': [-1, 0, 1]}, {'args': {}, 'factory_name':
        IsFirstFactory.name, 'offsets': [-2, -1, 0]}, {'args': {},
        'factory_name': IsLastFactory.name, 'offsets': [0, 1, 2]}, {'args':
        {'n': 1}, 'factory_name': ShapeNgramFactory.name, 'offsets': [0]},
        {'args': {'n': 2}, 'factory_name': ShapeNgramFactory.name,
        'offsets': [-1, 0]}, {'args': {'n': 3}, 'factory_name':
        ShapeNgramFactory.name, 'offsets': [-1]}, {'args': {'use_stemming':
        False, 'tagging_scheme_code': TaggingScheme.BILOU.value},
        'factory_name': CustomEntityMatchFactory.name, 'offsets': [-2, -1,
        0], 'drop_out': 0.5}, {'args': {'tagging_scheme_code':
        TaggingScheme.BIO.value}, 'factory_name': BuiltinEntityMatchFactory
        .name, 'offsets': [-2, -1, 0]}]


def twos_comp(per_bytes, bits):
    """compute the 2's complement of int value val"""
    if per_bytes & 1 << bits - 1 != 0:
        per_bytes = per_bytes - (1 << bits)
    return per_bytes


def iter_slices(string, slice_length):
    """Iterate over slices of a string."""
    pos = 0
    while pos < len(string):
        yield string[pos:pos + slice_length]
        pos += slice_length


@classmethod
def get_by_uuid(cls, context, uuid):
    """Find a volume target based on its UUID.

        :param cls: the :class:`VolumeTarget`
        :param context: security context
        :param uuid: the UUID of a volume target
        :returns: a :class:`VolumeTarget` object
        :raises: VolumeTargetNotFound if no volume target with this UUID exists
        """
    db_target = cls.dbapi.get_volume_target_by_uuid(uuid)
    target = cls._from_db_object(context, cls(), db_target)
    return target


def gen_from_source(source):
    """Return generator from a source tuple.

    Source tuples are of the form (callable, args) where callable(\\*args)
    returns either a generator or another source tuple.
    This allows indefinite regeneration of data sources.
    """
    while isinstance(source, tuple):
        gen, args = source
        source = gen(*args)
    return source


def mergeSeriesOnTimestampRange(df_cpu, df_type, fields):
    """
  Upsamples df_type to df_cpu.
  Check unit test for an example
  """
    if df_type.iloc[0].name < df_type.iloc[-1].name:
        raise Exception(
            'Types Dataframe should be sorted descending for utils.mergeSeriesOnTimestampRange'
            )
    import numpy as np
    for f in fields:
        df_cpu[f] = None
    for index, row_type in df_type.iterrows():
        row_i = np.where(df_cpu.Timestamp <= row_type.name)[0]
        for f in fields:
            col_i = df_cpu.columns.get_loc(f)
            df_cpu.iloc[row_i, col_i] = row_type[f]
    for f in fields:
        df_cpu[f] = df_cpu[f].fillna(method='backfill')
    return df_cpu


def get_quoted_user_id(status):
    """
    Retrieve the user id of the original tweet
    :param status: Tweet object
    :return: user id or None
    """
    try:
        return status.quoted_status.user.id if status.is_quote_status else None
    except AttributeError:
        return None


def exclude_paths(root, exclude, dockerfile, client):
    """
    Exclude paths from the build context.

    * root: root file path
    * exclude: exclude patterns
    * dockerfile: *Dockerfile* file-path in the context
    * client: containerization context
    * **return:** filtered files
    """
    files = client.exclude_paths_from_context(root, exclude, dockerfile)
    return files


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


@classmethod
def get_callback(cls, *arguments):
    """Get a callback function for the AST."""
    raise NotImplementedError(
        'Function {} can only be processed in a transpiler'.format(cls.name))


@classmethod
def has_resuming(cls):
    """Returns whether it supports to resume the fetch process.

        :returns: this backend supports items resuming
        """
    return True


def get_version_v2(uri):
    """
    Canned response nova v2 version.

    Cf: http://developer.openstack.org/api-ref-compute-v2.1.html
    #listVersionsv2.1
    """
    return {'version': {'status': 'SUPPORTED', 'updated':
        '2011-01-21T11:33:21Z', 'links': [{'href': uri, 'rel': 'self'}, {
        'href': 'http://docs.openstack.org/', 'type': 'text/html', 'rel':
        'describedby'}], 'min_version': '', 'version': '', 'media-types': [
        {'base': 'application/json', 'type':
        'application/vnd.openstack.compute+json;version=2'}]}}


def wxview(html, url='', size=(850, 540)):
    """View HTML in a wx dialog"""
    import wx
    from wx.html2 import WebView
    frame = wx.Frame(None, -1, size=size)
    view = WebView.New(frame)
    view.SetPage(html, url)
    frame.Show()
    return frame


def get_schema():
    """Schema structure of this resource

    :return: schema dictionary
    :rtype: dict
    """
    return {'mongo_indexes': {'index_updated': [('_updated', 1)],
        'index_name': [('name', 1)]}, 'schema': {'schema_version': {'type':
        'integer', 'default': 1}, 'imported_from': {'schema_version': 1,
        'title': 'Imported from', 'comment':
        'Item importation source (alignak-backend-import, ...)', 'type':
        'string', 'default': 'unknown'}, 'definition_order': {
        'schema_version': 1, 'title': 'Definition order', 'comment':
        'Priority level if several elements have the same name', 'type':
        'integer', 'default': 100}, 'name': {'schema_version': 1, 'title':
        'Command name', 'comment': 'Unique command name', 'type': 'string',
        'required': True, 'empty': False, 'unique': True}, 'alias': {
        'schema_version': 1, 'title': 'Alias', 'comment':
        'Element friendly name used by the Web User Interface.', 'type':
        'string', 'default': ''}, 'notes': {'schema_version': 1, 'title':
        'Notes', 'comment':
        'Element notes. Free text to store element information.', 'type':
        'string', 'default': ''}, 'command_line': {'schema_version': 1,
        'title': 'Command line', 'comment':
        'System command executed to run the command.', 'type': 'string'},
        'module_type': {'schema_version': 1, 'title': 'Module type',
        'comment':
        'A specific module type may be defined to associate commands to a dedicated worker. To be completed...'
        , 'type': 'string', 'default': 'fork'}, 'timeout': {
        'schema_version': 1, 'title': 'Timeout', 'comment':
        'Maximum command execution time before ALignak force the command stop.'
        , 'type': 'integer', 'default': -1}, 'enable_environment_macros': {
        'schema_version': 1, 'title': 'Environment macros', 'comment':
        'Set Alignak environment macros before running this command.',
        'type': 'boolean', 'default': False}, 'poller_tag': {
        'schema_version': 1, 'title': 'Poller tag', 'comment':
        'Set a value for this element checks to be managed by a dedicated poller.'
        , 'type': 'string', 'default': ''}, 'reactionner_tag': {
        'schema_version': 1, 'title': 'Reactionner tag', 'comment':
        'Set a value for this element notifications to be managed by a dedicated reactionner.'
        , 'type': 'string', 'default': ''}, '_realm': {'schema_version': 1,
        'title': 'Realm', 'comment': 'Realm this element belongs to.',
        'type': 'objectid', 'data_relation': {'resource': 'realm',
        'embeddable': True}, 'required': True}, '_sub_realm': {
        'schema_version': 1, 'title': 'Sub-realms', 'comment':
        'Is this element visible in the sub-realms of its realm?', 'type':
        'boolean', 'default': True}, '_users_read': {'schema_version': 1,
        'type': 'list', 'schema': {'type': 'objectid', 'data_relation': {
        'resource': 'user', 'embeddable': True}}}, '_users_update': {
        'schema_version': 1, 'type': 'list', 'schema': {'type': 'objectid',
        'data_relation': {'resource': 'user', 'embeddable': True}}},
        '_users_delete': {'schema_version': 1, 'type': 'list', 'schema': {
        'type': 'objectid', 'data_relation': {'resource': 'user',
        'embeddable': True}}}}, 'schema_deleted': {}}


def load_name(cg, name, local_names):
    """ Load a name onto the TOS.

    If the name exists in the local names set, it is loaded from
    the fast locals. Otherwise, it is loaded from the globals.

    Parameters
    ----------
    cg : CodeGenerator
        The code generator with which to write the code.

    name : str
        The name of the value to load onto the TOS.

    local_names : set
        The set of fast local names available to the code object.

    """
    if name in local_names:
        cg.load_fast(name)
    else:
        cg.load_global(name)


def theta_K_Mg_HMW84(T, P):
    """c-c': potassium magnesium [HMW84]."""
    theta = 0.0
    valid = T == 298.15
    return theta, valid


def user_confirm(prompt):
    """ Prompt user for confirmation. """
    ans = input(prompt)
    if len(ans) > 0:
        return ans[0] == 'y' or ans[0] == 'Y'
    return False


def _get_milliseconds_suffix(secs):
    """Return a formatted millisecond suffix, either empty if ms = 0, or dot with 3 digits otherwise.

    :param secs: a unix timestamp (integer or float)
    """
    ms_suffix = ''
    msecs = int(round(secs - int(secs), 3) * 1000)
    if msecs != 0:
        ms_suffix = '.%03i' % msecs
    return ms_suffix


def validate_vector_shape(name, shape, nrows, nobs):
    """
    Validate the shape of a possibly time-varying vector, or raise an exception

    Parameters
    ----------
    name : str
        The name of the vector being validated (used in exception messages)
    shape : array_like
        The shape of the vector to be validated. May be of size 1 or (if
        the vector is time-varying) 2.
    nrows : int
        The expected number of rows (elements of the vector).
    nobs : int
        The number of observations (used to validate the last dimension of a
        time-varying vector)

    Raises
    ------
    ValueError
        If the vector is not of the desired shape.
    """
    ndim = len(shape)
    if ndim not in [1, 2]:
        raise ValueError(
            'Invalid value for %s vector. Requires a 1- or 2-dimensional array, got %d dimensions'
             % (name, ndim))
    if not shape[0] == nrows:
        raise ValueError(
            'Invalid dimensions for %s vector: requires %d rows, got %d' %
            (name, nrows, shape[0]))
    if nobs is None and not (ndim == 1 or shape[-1] == 1):
        raise ValueError(
            'Invalid dimensions for %s vector: time-varying vectors cannot be given unless `nobs` is specified (implicitly when a dataset is bound or else set explicity)'
             % name)
    if ndim == 2 and not shape[1] in [1, nobs]:
        raise ValueError(
            'Invalid dimensions for time-varying %s vector. Requires shape (*,%d), got %s'
             % (name, nobs, str(shape)))


def parse_duration(duration):
    """
    Convert to duration used by lib.date.  Supports d, w, m, y
    """
    try:
        return int(duration), 'd'
    except:
        units, duration = duration[-1].lower(), duration[:-1]
        if units in 'dwmy':
            return int(duration), units
        else:
            raise


def temp_separation_ts(T_c, fc, T_air, t0):
    """Compute soil temperature

    Parameters
    ----------
    T_c : ee.Image
        Canopy temperature (Kelvin).
    fc : ee.Image
    T_air : ee.Image
        Air temperature (Kelvin).
    t0

    Returns
    -------
    T_s : ee.Image

    """
    Delta = fc.expression('(t0 ** 4) - (fc * (T_c ** 4))', {'fc': fc, 't0':
        t0, 'T_c': T_c})
    Delta = Delta.where(Delta.lte(0), 10)
    T_s = fc.expression('(Delta / (1 - fc)) ** 0.25', {'Delta': Delta, 'fc':
        fc}).where(fc.expression('((t0 ** 4) - (fc * T_c ** 4)) <= 0.', {
        'fc': fc, 't0': t0, 'T_c': T_c}), fc.expression(
        '(t0 - (fc * T_c)) / (1 - fc)', {'fc': fc, 't0': t0, 'T_c': T_c})
        ).where(fc.lt(0.1), t0).where(fc.gt(0.9), t0)
    T_s = T_s.where(T_s.lte(T_air.subtract(10.0)), T_air.subtract(10.0))
    T_s = T_s.where(T_s.gte(T_air.add(50.0)), T_air.add(50.0))
    return T_s


def check_r_s_same_size(R, S):
    """
    Raises an exception if R and S have different number of distinct elements

    Args:
        R (list of list): the gold standard
        S (list of list): the partition, output of the entity resolution that we want to evaluate
    """
    R_set = set()
    S_set = set()
    for i, val in enumerate(R):
        for j, rec in enumerate(val):
            R_set.add(rec)
    for i, val in enumerate(S):
        for j, rec in enumerate(val):
            S_set.add(rec)
    if len(R_set) != len(S_set):
        raise ValueError(
            'R and S have different numbers of distincts records : R has',
            len(R_set), 'distinct records while S has', len(S_set),
            'distinct records')


def snowpack_albedo(solutions, Gp, mu):
    """compute the albedo of the snowpack at one wavelength

    :param solutions: coefficients A et B pour chaque couche qui permttent calcul analytique des flux dans tous le manteau
    :type solutions: array
    :param Gp: coefficients Gm calculated for each layer
    :type Gp: array
    :param mu: cosine of the incident angle of intensity
    :ype mu:

    :returns: albedo at one wavelength (W/m^2)
"""
    if solutions is None:
        return 0
    solution_C = solutions[2]
    solution_D = solutions[3]
    albedo = (solution_C[0] + solution_D[0] + Gp[0]) / mu
    return albedo


def sql_flush(style, connection, only_django=False, reset_sequences=True,
    allow_cascade=False):
    """
    Return a list of the SQL statements used to flush the database.

    If only_django is True, only include the table names that have associated
    Django models and are in INSTALLED_APPS .
    """
    if only_django:
        tables = connection.introspection.django_table_names(only_existing=
            True, include_views=False)
    else:
        tables = connection.introspection.table_names(include_views=False)
    seqs = connection.introspection.sequence_list() if reset_sequences else ()
    statements = connection.ops.sql_flush(style, tables, seqs, allow_cascade)
    return statements


def sorted_items(params):
    """Return an iterator of the dict's items sorted by its keys."""
    return sorted(params.items())


def dq_dv_engine(**kwargs):
    """engine that performs incremental analysis of the cycle-data"""
    farms = None
    barn = 'raw_dir'
    return farms, barn


def _silence_resource_warning(popen):
    """Silence Popen's ResourceWarning.

    Note this should only be used if the process was created as a daemon.
    """
    popen.returncode = 0


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

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


def to_text(string):
    """Ensure that the string is text."""
    if callable(getattr(string, 'decode', None)):
        return string.decode('utf-8')
    return string


def db_list(client, server_name, resource_group_name, elastic_pool_name=None):
    """
    Lists databases in a server or elastic pool.
    """
    if elastic_pool_name:
        return client.list_by_elastic_pool(server_name=server_name,
            resource_group_name=resource_group_name, elastic_pool_name=
            elastic_pool_name)
    return client.list_by_server(resource_group_name=resource_group_name,
        server_name=server_name)


def _contrib_round_ste(data=None, name=None, attr=None, out=None, **kwargs):
    """Straight-through-estimator of `round()`.

    In forward pass, returns element-wise rounded value to the nearest integer of the input (same as `round()`).

    In backward pass, returns gradients of ``1`` everywhere (instead of ``0`` everywhere as in `round()`):
    :math:`\\frac{d}{dx}{round\\_ste(x)} = 1` vs. :math:`\\frac{d}{dx}{round(x)} = 0`.
    This is useful for quantized training.

    Reference: Estimating or Propagating Gradients Through Stochastic Neurons for Conditional Computation.

    Example::
      x = round_ste([-1.5, 1.5, -1.9, 1.9, 2.7])
      x.backward()
      x = [-2.,  2., -2.,  2.,  3.]
      x.grad() = [1.,  1., 1.,  1.,  1.]

    The storage type of ``round_ste`` output depends upon the input storage type:
      - round_ste(default) = default
      - round_ste(row_sparse) = row_sparse
      - round_ste(csr) = csr

    Defined in src/operator/contrib/stes_op.cc:L55

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

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

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


@staticmethod
def reverse(string):
    """Reverse string sequence"""
    return string.upper()[::-1]


@classmethod
def exists(cls, shark, path):
    """Returns true if the resource exists, false otherwise
        """
    assert shark is not None
    assert path is not None and len(path) > 0
    try:
        shark.api.fs.get_details(path)
    except Exception:
        return False
    else:
        return True


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

        :param list of [str] val:
        :rtype: UsersSelectorArg
        """
    return cls('emails', val)


def bytes_to_readable(num, power='M'):
    """Converts numerical value into human readable memory value."""
    powers = ['B', 'K', 'M', 'G', 'T']
    while num >= 1000:
        num /= 1024.0
        next_power_idx = powers.index(power) + 1
        if next_power_idx == len(powers):
            break
        power = powers[next_power_idx]
    return '%.1f%s' % (num, power)


def adjust(date, close, adj_close, in_col, rounding=4):
    """
    If using forex or Crypto - Change the rounding accordingly!
    """
    try:
        factor = adj_close / close
        return round(in_col * factor, rounding)
    except ZeroDivisionError:
        print('WARNING: DIRTY DATA >> {} Close: {} | Adj Close {} | in_col: {}'
            .format(date, close, adj_close, in_col))
        return 0


def bench1_with_time(x):
    """Same as bench1 but returns the computation time (constant)."""
    return x[0] ** 2, 2.22


def prepare_molecules(mol1, mol2, aligned_suffix='', save_aligned=False,
    align=True):
    """Prepare two molecules for the scanning procedure. First, align mol1
    and mol2 with their centers to org and their third and second main
    axes with [1,0,0] and [0,1,0], respectively.  Then, append mol2 to mol1 and
    enable tagging to allow easily moving mol2 with one command.  The
    OBAggregate object is returned.

    Args:
        mol1: (object of type ManipulateAggregates.aggregate.agg) the molecule
            that is to be kept fixed during the scan
        mol2: (object of type ManipulateAggregates.aggregate.agg) the molecule
            that is to be moved around during the scan
        aligned_suffix: (string) add this to the original file names to get
            the files to which the aligned geometries shall be saved
        save_aligned: (bool) whether or not to save the aligned geometries
        align: (bool) whether or not to perform the alignment procedure

    Returns:
        an OBAggregate object that contains mol1 and mol2
    """
    nr_scan_mols = mol2.obmol.GetNrMolecules()
    nr_fix_mols = mol1.obmol.GetNrMolecules()
    if align:
        mol1.align([0, 0, 0], [1, 0, 0], [0, 1, 0])
        mol2.align([0, 0, 0], [1, 0, 0], [0, 1, 0])
        if save_aligned:
            mol1.write(mol1.info['name'] + aligned_suffix)
            mol2.write(mol2.info['name'] + aligned_suffix)
    else:
        mol1.obmol.Center()
        mol2.obmol.Center()
    mol1.append(mol2)
    obmol = mol1.obmol
    obmol.EnableTags()
    tag = obmol.CreateTag(nr_scan_mols)
    for i in range(nr_fix_mols, nr_fix_mols + nr_scan_mols):
        obmol.AddToTag(i, tag)
    return obmol


@staticmethod
def status_ok(status_code):
    """Check whether a status code is OK"""
    OK_STATUS_CODES = [200, 201]
    return status_code in OK_STATUS_CODES


def _margeff_cov_params_dummy(model, cov_margins, params, exog, dummy_ind,
    method, J):
    """
    Returns the Jacobian for discrete regressors for use in margeff_cov_params.

    For discrete regressors the marginal effect is

    \\Delta F = F(XB) | d = 1 - F(XB) | d = 0

    The row of the Jacobian for this variable is given by

    f(XB)*X | d = 1 - f(XB)*X | d = 0

    Where F is the default prediction of the model.
    """
    for i in dummy_ind:
        exog0 = exog.copy()
        exog1 = exog.copy()
        exog0[:, (i)] = 0
        exog1[:, (i)] = 1
        dfdb0 = model._derivative_predict(params, exog0, method)
        dfdb1 = model._derivative_predict(params, exog1, method)
        dfdb = dfdb1 - dfdb0
        if dfdb.ndim >= 2:
            dfdb = dfdb.mean(0)
        if J > 1:
            K = dfdb.shape[1] // (J - 1)
            cov_margins[i::K, :] = dfdb
        else:
            cov_margins[(i), :len(dfdb)] = dfdb
    return cov_margins


def is_valid_minute(minute):
    """
    Check if minute value is valid
    :param minute: int|string
    :return: boolean
    """
    return minute == '*' or 59 >= minute >= 0


def get_topics(yaml_info):
    """ Returns the names of all of the topics in the bag, and prints them
        to stdout if requested
    """
    names = []
    topics = yaml_info['topics']
    for topic in topics:
        names.append(topic['topic'])
    return names


@classmethod
def create(cls, filename, compression, sources):
    """
        Create the archive
        :param filename: name of the archive
        :type filename: str
        :param compression: compression mode
        :type compression: str
        :param sources: files to be archived
        :type sources: list
        """
    raise NotImplementedError


def get_embedded_author(embedded):
    """Returns the author in the embedded response from wp.
    embedded["author"]

    :param embedded: The embedded dictionnary in the response
    :returns: Dictionnary of author
    """
    authors = embedded.get('author', [{}])
    return authors[0]


def group_unassign():
    """Remove selected bones from all bone groups

    """
    pass


def color_delete():
    """Remove active color from palette

    """
    pass


def quote_path(v):
    """
    Quote the path if it is not already quoted.

    If v starts with '-', then assume that it is a -I option or similar
    and do not quote it.  This is fragile:  -Ipath with space needs to
    be quoted.
    """
    return '"' + v + '"' if v and ' ' in v and not v[0] in '"\'-' else v


def plot_fleur_dos_wc(node, labels=None):
    """
    This methods takes an AiiDA output parameter node from a density of states
    workchain and plots a simple density of states
    """
    from masci_tools.vis.plot_methods import plot_dos
    if labels is None:
        labels = []
    if isinstance(node, list):
        if len(node) > 2:
            return
        else:
            node = node[0]
    output_d = node.get_dict()
    path_to_dosfile = output_d.get('dosfile', None)
    print(path_to_dosfile)
    if path_to_dosfile:
        plot_dos(path_to_dosfile, only_total=False)
    else:
        print('Could not retrieve dos file path from output node')


def get_file(message, default=None):
    """ Get a reference to a file and make sure it exists

    Returns:
        path: The path to the file, if it exists

    Raises:
        ValueError: If the provided file does not exist
    """
    if default:
        path = input('{} ({}): '.format(message, default))
    else:
        path = input('{}: '.format(message))
    return path


def check_experiment_existence(topic_model):
    """
    Checks if topic_model has experiment.

    Parameters
    ----------
    topic_model : TopicModel
        topic model

    Returns
    -------
    bool
        True if experiment exists, in other case False.

    """
    is_experiment = topic_model.experiment is not None
    return is_experiment


def p_declaration_1(t):
    """declaration : type_specifier ID"""
    t[1].id = t[2]
    t[0] = t[1]


def Cv_to_K(Cv, D):
    """Convert imperial valve flow coefficient from imperial units to regular
    loss coefficients.

    .. math::
        K = 1.6\\times 10^9 \\frac{D^4}{\\left(\\frac{C_v}{1.56}\\right)^2}

    Parameters
    ----------
    Cv : float
        Imperial Cv valve flow coefficient (flow rate of water at a pressure
        drop of 1 psi) [gallons/minute]
    D : float
        Inside diameter of the valve [m]

    Returns
    -------
    K : float
        Loss coefficient, [-]

    Notes
    -----
    The exact conversion coefficient between Kv to Cv is 1.1560992283536566;
    it is rounded in the formula above.

    Examples
    --------
    >>> Cv_to_K(2.712, .015)
    14.719595348352552

    References
    ----------
    .. [1] ISA-75.01.01-2007 (60534-2-1 Mod) Draft
    """
    return 1600000000.0 * D ** 4 * (Cv / 1.1560992283536566) ** -2


def _encode_utf8(string):
    """Converts argument to UTF-8-encoded bytes.

    Used to make dict lookups work in Python 3 because topics and things are
    bytes.
    """
    return string.encode('utf-8', errors='replace')


def construct_surl_T0(dsn, filename):
    """
    Defines relative SURL for new replicas. This method
    contains Tier0 convention. To be used for non-deterministic sites.

    @return: relative SURL for new replica.
    @rtype: str
    """
    fields = dsn.split('.')
    nfields = len(fields)
    if nfields >= 3:
        return '/%s/%s/%s/%s/%s' % (fields[0], fields[2], fields[1], dsn,
            filename)
    elif nfields == 1:
        return '/%s/%s/%s/%s/%s' % (fields[0], 'other', 'other', dsn, filename)
    elif nfields == 2:
        return '/%s/%s/%s/%s/%s' % (fields[0], fields[2], 'other', dsn,
            filename)
    elif nfields == 0:
        return '/other/other/other/other/%s' % filename


@classmethod
def get_provider_by_provider_id(cls, provider_id, store):
    """Get a provider given a provider id string
        :param provider_id: a string representing the provider
        :param store: a database store
        """
    return store.find(cls, provider_id=provider_id)


def get_message_id(message):
    """Sanitizes the 'reply_to' parameter a user may send"""
    if message is None:
        return None
    if isinstance(message, int):
        return message
    if hasattr(message, 'original_message'):
        return message.original_message.id
    try:
        if message.SUBCLASS_OF_ID == 2030045667:
            return message.id
    except AttributeError:
        pass
    raise TypeError('Invalid message type: {}'.format(type(message)))


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

        :param MemberSendInvitePolicyChangedType val:
        :rtype: EventType
        """
    return cls('member_send_invite_policy_changed', val)


@staticmethod
def _get_normalized_translations(vertex):
    """
        Compute the translations corresponding to the merdian and longitude of
        the given cusp.
        """
    m, l = vertex.Translations
    return m / l * abs(l), abs(l)


def save_plist(data_dict, file_path):
    """
    save a dict as a plist file
    :param data_dict: dict data
    :param file_path: plist file path to save
    :return:
    """
    import plistlib
    if hasattr(plistlib, 'dump'):
        with open(file_path, 'wb') as fp:
            plistlib.dump(data_dict, fp)
    else:
        plistlib.writePlist(data_dict, file_path)


def calculate_track_length_distribution2():
    """Calculates the model track length distribution for the given time-
    temperature history.  For each T-t segment, it finds the reduced
    mean and standard deviation for the population of track lengths based
    on the model of Laslett et al. (1987).  The tiq calculation uses
    Goswami et al. (1984) and Duddy et al. (1988).
    """
    return


def check_treedepth(samples, max_treedepth=10, quiet=False,
    return_diagnostics=False):
    """Check transitions that ended prematurely due to maximum tree depth limit.

    Parameters
    ----------
    samples : ArviZ InferenceData instance
        Contains samples to be checked. Must contain both `posterior`
        and `samples_stats`.
    max_treedepth: int, default 10
        Maximum tree depth used in the calculation.
    quiet : bool, default False
        If True, do not print diagnostic result to the screen.
    return_diagnostics : bool, default False
        If True, return both a Boolean about whether the diagnostic
        passed and the number of samples where the tree depth was too
        deep. Otherwise, only return Boolean if the test passed.

    Returns
    -------
    passed : bool
        Return True if tree depth test passed. Return False otherwise.
    n_too_deep : int, optional
        Number of samplers wherein the tree depth was greater than
        `max_treedepth`.
    """
    n_too_deep = (samples.sample_stats.treedepth.values >= max_treedepth).sum()
    n_total = samples.sample_stats.dims['chain'] * samples.sample_stats.dims[
        'draw']
    if not quiet:
        msg = '{} of {} ({}%) iterations saturated'.format(n_too_deep,
            n_total, 100 * n_too_deep / n_total)
        msg += ' the maximum tree depth of {}.'.format(max_treedepth)
        print(msg)
    pass_check = n_too_deep == 0
    if not pass_check and not quiet:
        print(
            '  Try running again with max_treedepth set to a larger value' +
            ' to avoid saturation.')
    if return_diagnostics:
        return pass_check, n_too_deep
    return pass_check


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


@classmethod
def from_row(cls, row, select_related=None):
    """
        Instantiate a model instance, given a database row.
        """
    select_related = select_related or []
    item = {}
    for related in select_related:
        if '__' in related:
            first_part, remainder = related.split('__', 1)
            model_cls = cls.__fields__[first_part].type_.to
            item[first_part] = model_cls.from_row(row, select_related=[
                remainder])
        else:
            model_cls = cls.__fields__[related].type_.to
            item[related] = model_cls.from_row(row)
    for column in cls.Mapping.table.columns:
        if column.name not in item:
            col_type = cls.__fields__[column.name].type_
            value = row[column]
            if col_type.__name__ == 'ForeignKey':
                item[column.name] = col_type.to(pk=value, __pk_only__=True)
            else:
                item[column.name] = value
    return cls(**item)


def condense_output(output):
    """WW: what is this weird construct doing ???? It seems like it does things very complicated"""
    results = {}
    for i in range(len(output)):
        resultsDict = output[i]
        keys = list(resultsDict.keys())
        for j in range(len(resultsDict)):
            key = keys[j]
            results[key] = resultsDict[key]
    return results


def ensure_nolatex(string):
    """Removes $'s at the beginning and end of the string, if necessary."""
    return string.strip().lstrip('$').rstrip('$')


def _create_html_file_content(translations):
    """Create html string out of translation dict.

    Parameters
    ----------
    tralnslations : dict
        Dictionary of word translations.

    Returns
    -------
    str:
        html string of translation
    """
    content = []
    for i1, t in enumerate(translations):
        if i1 > 0:
            content.append('
')
        content.append('
')
        content.append('
')
        for w in t.word:
            content.append('
{word}
'.format(word=w))
        content.append('
')
        for i2, t2 in enumerate(t.parts_of_speech):
            if i2 > 0:
                content.append('
')
            content.append('
')
            if t2.part is not None:
                content.append('
[{part}]
'.format(
                    part=t2.part))
            content.append('
')
            for m in t2.meanings:
                content.append('
')
                mng = ['
']
                for i3, mn in enumerate(m.meaning):
                    if i3 > 0:
                        mng.append(', ')
                    mng.append('{meaning}'.format(meaning=mn))
                mng.append('
')
                content.append(''.join(mng))
                content.append('
')
                for e in m.examples:
                    exmpl = '
{ex}'.format(ex=e[0])
                    if e[1]:
                        exmpl += '
{tr}'.format(tr=e[1])
                    exmpl += '
'
                    content.append(exmpl)
                content.append('
')
                content.append('
')
            content.append('
')
            content.append('
')
        content.append('
')
    return '\n'.join(content)


def connectors_to_end(elem):
    """ Move connectors to the end of element """
    connectors = elem.find('./connectors')
    if connectors is not None:
        elem.remove(connectors)
        elem.append(connectors)


@staticmethod
def filter_python_files(files):
    """
        param files: list of strings -> File names

        For a list of file name strings. it returns
        only those that are a Python file
        """
    return list(filter(lambda file: file[-2:] == 'py', files))


def days_to_seconds(days):
    """Takes a time in fractional days and converts it into integer seconds."""
    return int(round(86400 * days))


def p_type_specifier_list(t):
    """type_specifier_list : COMMA type_specifier type_specifier_list
                           | empty"""


def ScenarioCheck(Sig, Val, ArraySizes):
    """
	Return a string of scenario GPIO CHECK command for TBGen.
	"""
    CheckString = ''
    if Sig.Type == 'logic':
        SIZE = Sig.GetSize()
        if SIZE == 1:
            CheckString += '\nGPIO CHECK {Name} {Value}'.format(Name=Sig.
                Name, Value=0 if Val == 0 else 1)
        else:
            CheckString += (
                '\nGPIO CHECK_VECT {Name}_{MSb} {Name}_0 {Value:#010x}'.
                format(Name=Sig.Name, MSb=SIZE - 1, Value=Val))
    else:
        for j in range(ArraySizes[Sig.Type]):
            CheckString += (
                '\nGPIO CHECK_VECT {Name}_{MSb} {Name}_0 {Value:#010x}'.
                format(Name=Sig.Name, MSb=SIZE - 1, Value=Val))
    return CheckString


def get_trf_command(command, transformation=''):
    """
    Return the last command in the full payload command string.
    Note: this function returns the last command in job.command which is only set for containers.

    :param command: full payload command (string).
    :param transformation: optional name of transformation, e.g. Sim_tf.py (string).
    :return: trf command (string).
    """
    payload_command = ''
    if command:
        if not transformation:
            payload_command = command.split(';')[-2]
        elif transformation in command:
            payload_command = command[command.find(transformation):]
        payload_command = payload_command.strip()
        payload_command = payload_command.replace("'", '')
        payload_command = payload_command.rstrip(';')
    return payload_command


def is_dataset(obj):
    """Verfy if a object is ``dataset-like`` defined in
    :class:`torch.utils.data.Dataset`.

    Args:
        obj: Object to be determined.

    Returns:
        bool: True for ``dataset-like`` object, false otherwise.

    """
    return hasattr(obj, '__getitem__') and hasattr(obj, '__len__')


def bytes2str(s):
    """ Handle suprocess routines often return bytes instead of str in python3,
    which is different from python2 """
    if hasattr(s, 'decode'):
        return s.decode()
    else:
        return s


def destinations(mlist):
    """Generate just the local parts for the mailing list aliases.

        This method is a generator.  The posting address will be returned
        first, followed by the rest of the aliases in alphabetical order.

        :param mlist: The mailing list.
        :type mlist: An `IMailingList` or an object with a `list_name`
            attribute.
        :return: The set of short (i.e. without the @dom.ain part) common
            aliases for the mailing list.
        :rtype: string
        """


@classmethod
def update_or_create(cls, db_session, mapper, attributes):
    """
        Updated the record if attributes contain the primary key value(s) and creates it if they don't.

        :param db_session:
        :type db_session: sqlalchemy.orm.session.Session

        :param mapper:
        :type mapper: sqlalchemy.orm.mapper.Mapper

        :param attributes:
        :type attributes: dict

        :return:
        :rtype: object
        """
    query_attrs = {}
    for key in mapper.primary_key:
        if key in attributes:
            query_attrs[key] = attributes.pop(key)
    if query_attrs:
        obj = db_session.query(mapper.class_).get(query_attrs[0] if len(
            query_attrs) == 1 else tuple(query_attrs))
    else:
        obj = mapper.class_()
    if attributes:
        return cls.save_resource(obj, attributes, db_session)
    return obj


def _config_info(mode, config):
    """Generate info about the config."""
    return {'mode': mode, 'views': len(config.get('views', []))}


def _test_args():
    """Extra arguments to use when zipline's automated tests run this example.
    """
    import pandas as pd
    return {'start': pd.Timestamp('2014-01-01', tz='utc'), 'end': pd.
        Timestamp('2014-11-01', tz='utc')}


def store(json_conf):
    """Store the given configuration.
        """


def _sorted_edge(u, v):
    """Returns a sorted edge.

    During the construction of a line graph for undirected graphs, the data
    structure can be a multigraph even though the line graph will never have
    multiple edges between its nodes.  For this reason, we must make sure not
    to add any edge more than once.  This requires that we build up a list of
    edges to add and then remove all duplicates.  And so, we must normalize
    the representation of the edges.

    """
    return (u, v) if u <= v else (v, u)


def get_paginated_generator(api_client):
    """This generator can be used to get() paginated results

    If 'api_client' is a Slumber resource, you can use this generator
    as so:

      for doc in get_paginated_generator(api_client):
          pass

    and if the remote PopIt instance returns paginated results, it
    will return all them, whereas the following:

      for doc in api_client.get()['result']:
          pass

    ... would only return the first page."""
    page = 1
    keep_fetching = True
    while keep_fetching:
        response = api_client.get(per_page=50, page=page)
        keep_fetching = response.get('has_more', False)
        page += 1
        for doc in response['result']:
            yield doc


@classmethod
def success(cls, response=200, **kwargs):
    """Сообщение об успехе.

        Args:
            response: код ответа (default: {200})
            **kwargs: доп. параметры

        Returns:
            Возвращает себя инициализированного
            Message

        """
    return cls(response=response, **kwargs)


def normalize_header_name(header_name):
    """
    Normalizes an header name to lower case, stripping all its leading and trailing white spaces.
    :param header_name: the header name to normalize
    :type header_name: str
    :return: the normalized header name
    :rtype: str
    """
    return header_name.strip().lower() if header_name is not None else None


def _cal_constants(x, y):
    """Calcula as constantes '𝛂', 'h' e 'k'."""
    h = x[-1] / (x.size - 1)
    k = y[-1] / (y.size - 1)
    α = k ** 2 / h ** 2
    return α, h, k


def get_swagger_version(obj):
    """ get swagger version from loaded json """
    if isinstance(obj, dict):
        if 'swaggerVersion' in obj:
            return obj['swaggerVersion']
        elif 'swagger' in obj:
            return obj['swagger']
        return None
    else:
        return obj.swaggerVersion if hasattr(obj, 'swaggerVersion'
            ) else obj.swagger


def has_permission(perm, user, obj):
    """ Check whether the user has the permisson on the object (or the
    objects' permission_authority)."""
    authority = getattr(obj, 'permission_authority', obj)
    if not authority:
        return True
    return user.has_perm(perm, obj=authority)


@staticmethod
def get_default_config():
    """Get default configuration."""
    return {}


@staticmethod
def correct_tip_offset(apret):
    """Correct the offset of the tip position

        An estimate of the tip position is used to compute the
        contact point.
        """
    cpid = apret.estimate_contact_point_index()
    apret.data['tip position'] -= apret.data['tip position'][cpid]


def csv_list(value):
    """
    Convert a comma separated string into a list

    Parameters
    ----------
    value : str
        The string object to convert to a list

    Returns
    -------
    list
        A list based on splitting the string on the ',' character
    """
    if value:
        result = []
        for item in value.split(','):
            item = item.strip()
            if item:
                result.append(item)
        return result
    return []


def _sanity_check(name, package, level):
    """Verify arguments are "sane"."""
    if not isinstance(name, str):
        raise TypeError('module name must be str, not {}'.format(type(name)))
    if level < 0:
        raise ValueError('level must be >= 0')
    if level > 0:
        if not isinstance(package, str):
            raise TypeError('__package__ not set to a string')
        elif not package:
            raise ImportError(
                'attempted relative import with no known parent package')
    if not name and level == 0:
        raise ValueError('Empty module name')


def backimage_zoom(factor: float=1.2):
    """Zoom in/out the background image

    :param factor: Factor
    :type factor: float
    """
    pass


@classmethod
def get_raw_static(cls, index):
    """
            Must be used internally by UOFiddler?
        :return: bytes --
        """
    index = cls.get_legal_item_id(index)
    index += 16384
    stream, length, extra, patched = cls._file_index.seek(index)
    if not stream:
        return None
    return stream.read(length)


def max_tok_len(new, count, sofar):
    """
    In token batching scheme, the number of sequences is limited
    such that the total number of src/tgt tokens (including padding)
    in a batch <= batch_size
    """
    global max_src_in_batch, max_tgt_in_batch
    if count == 1:
        max_src_in_batch = 0
        max_tgt_in_batch = 0
    max_src_in_batch = max(max_src_in_batch, len(new.src[0]) + 2)
    max_tgt_in_batch = max(max_tgt_in_batch, len(new.tgt[0]) + 1)
    src_elements = count * max_src_in_batch
    tgt_elements = count * max_tgt_in_batch
    return max(src_elements, tgt_elements)


def insert_tag(el, add, before=True):
    """Insert element ('add') before or after element ('el').

    See `process.gen.add_hr` for doctest example.
    """
    parent = el.getparent()
    assert parent is not None
    num = parent.index(el)
    if not before:
        num = num + 1
    parent.insert(num, add)


def intervals_complement(intervals, length):
    """
	Given an iterable of sorted, nonoverlapping intervals as (start, stop)
	pairs, yield the complementary intervals. The result is equivalent to
	[(0, length)] minus the given intervals.

	>>> list(intervals_complement([(1, 2), (4, 6)], length=10))
	[(0, 1), (2, 4), (6, 10)]
	"""
    prev_stop = 0
    for start, stop in intervals:
        if start >= length:
            break
        if prev_stop != start:
            yield prev_stop, start
        prev_stop = stop
    if prev_stop < length:
        yield prev_stop, length


def downsample(N):
    """conditional that is true on every Nth sample"""
    global _downsample_N
    _downsample_N = (_downsample_N + 1) % N
    return _downsample_N == 0


def indeed_parameters(what, where):
    """Store parameters for use with the Indeed API.

    Positional arguments:
    what -- the description of the desired job
    where -- the location of the desired job

    :param q: job description
    :param l: job location; searches entire U.S. when left blank
    :param sort: sort results by relevance or date
    :param sr: direct hire only or include staffing agencies
    :param limit: number of results, 0-25
    :param fromage: number of days to search
    :param start: index of beginning search result
    :param userip: ip of client (required)
    :param useragent: user agent of client (required)
    """
    params = {'q': what, 'l': where, 'sort': 'date', 'sr': 'directhire',
        'limit': 25, 'fromage': 365, 'start': 0, 'userip': '1.2.3.4',
        'useragent':
        'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36(KHTML, like Gecko) Chrome/48.0.2564.82 Safari/537.36'
        }
    return params


def intersect_point_line(pt: 'mathutils.Vector', line_p1:
    'mathutils.Vector', line_p2) ->float:
    """Takes a point and a line and returns a tuple with the closest point on the line and its distance from the first point of the line as a percentage of the length of the line.

    :param pt: Point
    :type pt: 'mathutils.Vector'
    :param line_p1: First point of the line
    :type line_p1: 'mathutils.Vector'
    :param line_p1: Second point of the line
    """
    pass


def is_sequence(arg):
    """
    Checks if an object is iterable (you can loop over it) and not a string
    ** Taken from SHARKToolbox
    :param arg:
    :return:
    """
    return not hasattr(arg, 'strip') and hasattr(arg, '__iter__')


@classmethod
def from_system(cls, **kwargs):
    """Constructor that returns Environ instance pre-populated with values
        from the process environment.
        """
    env = cls(**kwargs)
    env.inherit()
    return env


def find_first(mylist, item):
    """ Returns index of the first occurence of item in mylist, returns -1 if not found """
    try:
        idx = mylist.index(item)
    except ValueError:
        idx = -1
    return idx


def connect(host, port):
    """
        Connect the transport to an address.

        This changes it to connected mode. Datagrams can only be sent to
        this address, and will only be received from this address. In addition
        the protocol's connectionRefused method might get called if destination
        is not receiving datagrams.

        @param host: an IP address, not a domain name ('127.0.0.1', not 'localhost')
        @param port: port to connect to.
        """


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


@classmethod
def deserialize(cls, serialized):
    """Deserializes from the Protobuf format.
        """
    if serialized.WhichOneof('layer_data') == 'hard_tanh_data':
        return cls()
    return None


def is_gzipped_fastq(file_name):
    """
    Determine whether indicated file appears to be a gzipped FASTQ.

    :param str file_name: Name/path of file to check as gzipped FASTQ.
    :return bool: Whether indicated file appears to be in gzipped FASTQ format.
    """
    parts = file_name.split('.')
    return parts[-2:] in [['fq', 'gz'], ['fastq', 'gz']]


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


def numberdict(dct):
    """ convert all numeric values in a dict to their appropriate type """
    o = {}
    for k, v in dct.items():
        if v.isdigit():
            v = int(v)
        else:
            try:
                v = float(v)
            except ValueError:
                v = v
        o.update({k: v})
    return o


def deprecation_handler(kwargs):
    """
    As things change from version to version, deal with them here.
    """
    if 0:
        if 'infer_gene_extent' in kwargs:
            raise ValueError(
                "'infer_gene_extent' is deprecated as of version 0.8.4 in favor of more granular control over inferring genes and/or transcripts.  The previous default was 'infer_gene_extent=True`, which corresponds to the new defaults 'disable_infer_genes=False' and 'disable_infer_transcripts=False'. Please see the docstring for gffutils.create_db for details."
                )
    if len(kwargs) > 0:
        raise TypeError('unhandled kwarg in %s' % kwargs)


@classmethod
def from_config(cls, cfg, **kw):
    """Alternative constructor makes object from config file settings
        @type cfg: basestring / ConfigParser derived type
        @param cfg: configuration file path or ConfigParser type object
        @rtype: ndg.saml.saml2.binding.soap.client.SOAPBinding or derived type
        @return: new instance of this class
        """
    obj = cls()
    obj.parse_config(cfg, **kw)
    return obj


def split_unescape(s, delim, escape='\\', unescape=True):
    """
        >>> split_unescape('foo,bar', ',')
        ['foo', 'bar']
        >>> split_unescape('foo$,bar', ',', '$')
        ['foo,bar']
        >>> split_unescape('foo$$,bar', ',', '$', unescape=True)
        ['foo$', 'bar']
        >>> split_unescape('foo$$,bar', ',', '$', unescape=False)
        ['foo$$', 'bar']
        >>> split_unescape('foo$', ',', '$', unescape=True)
        ['foo$']
        """
    ret = []
    current = []
    itr = iter(s)
    for ch in itr:
        if ch == escape:
            try:
                if not unescape:
                    current.append(escape)
                current.append(next(itr))
            except StopIteration:
                if unescape:
                    current.append(escape)
        elif ch == delim:
            ret.append(''.join(current))
            current = []
        else:
            current.append(ch)
    ret.append(''.join(current))
    return ret


def get_clusterid_for_cluster_mor(session, cluster_mor):
    """Return cluster id from cluster mor."""
    if cluster_mor:
        clusterid = cluster_mor.value
        return clusterid
    return None


def year_frac(start, end):
    """
    计算两个日期间的时间长度，以年为单位

    参数:
    start (datetime): start date
    end (datetime): end date

    """
    if start > end:
        raise ValueError('start cannot be larger than end')
    return (end - start).total_seconds() / 31557600


def disassociate_principal_from_portfolio(AcceptLanguage=None, PortfolioId=
    None, PrincipalARN=None):
    """
    Disassociates a previously associated principal ARN from a specified portfolio.
    See also: AWS API Documentation

    :example: response = client.disassociate_principal_from_portfolio(
        AcceptLanguage='string',
        PortfolioId='string',
        PrincipalARN='string'
    )

    :type AcceptLanguage: string
    :param AcceptLanguage: The language code to use for this operation. Supported language codes are as follows:
            'en' (English)
            'jp' (Japanese)
            'zh' (Chinese)
            If no code is specified, 'en' is used as the default.

    :type PortfolioId: string
    :param PortfolioId: [REQUIRED]
            The portfolio identifier.

    :type PrincipalARN: string
    :param PrincipalARN: [REQUIRED]
            The ARN representing the principal (IAM user, role, or group).

    :rtype: dict
    :return: {}

    :returns:
    (dict) --

    """
    pass


def render_pep440_old(pieces):
    """TAG[.postDISTANCE[.dev0]] .

    The ".dev0" means dirty.

    Eexceptions:
    1: no tags. 0.postDISTANCE[.dev0]
    """
    if pieces['closest-tag']:
        rendered = pieces['closest-tag']
        if pieces['distance'] or pieces['dirty']:
            rendered += '.post%d' % pieces['distance']
            if pieces['dirty']:
                rendered += '.dev0'
    else:
        rendered = '0.post%d' % pieces['distance']
        if pieces['dirty']:
            rendered += '.dev0'
    return rendered


def decclassdebugging(cl):
    """
    decorator for debugging classes.
    It allows to trigger specifically which method in a class will be observed.
    if debug(self) : " where debug is needed
    After instantiation of the class, add class.method_name_debug = True to activate the debugging.
    """
    for m in dir(cl):
        if len(m.split('__')) == 1:
            setattr(cl, m + '_debug', False)
    return cl


def is_tree(obj):
    """Determine if the object is a tree-like."""
    return hasattr(obj, 'documents')


def rfc3339_string(t):
    """转化 datetime 为 rfc3339 格式字符串"""
    return t.isoformat('T') + 'Z'


def system_updates_is_set_to_on_2_3(security_center):
    """
    New query param in 1.1 is properties.parameters.systemUpdatesMonitoringEffect
    but it is not in the output of the general api call.  Nor in az policy definition list.
    """
    items_flagged_list = []
    for item in security_center:
        resource_group = item['name']
        system_updates = item['properties']['recommendations']['patch']
        if system_updates != 'On':
            items_flagged_list.append(resource_group)
    stats = {'items_flagged': len(items_flagged_list), 'items_checked': len
        (security_center)}
    metadata = {'finding_name': 'system_updates_is_set_to_on',
        'negative_name': 'system_updates_not_on', 'columns': ['Resource Group']
        }
    return {'items': items_flagged_list, 'stats': stats, 'metadata': metadata}


def psi_Mg_Na_HCO3_HMW84(T, P):
    """c-c'-a: magnesium sodium bicarbonate [HMW84]."""
    psi = 0.0
    valid = T == 298.15
    return psi, valid


def out_of_range(n: int) ->bool:
    """
    Return True if `n` could not be represented as either a 16-bit signed or unsigned
    integer.
    """
    return n < -32768 or n >= 65536


@staticmethod
def getReal(data):
    """Return the real component of the given complex data. """
    return data.real


def round_to(x, base=1, prec=2):
    """
    Round to nearest base with precision.

    :param x: (scalar) - value to be rounded from
    :param base: (scalar) - value to be rounded to
    :param prec: (int) - number of decimal points
    :return rounded_val: (scalar) - rounded value
    """
    try:
        return round(base * round(float(x) / base), prec)
    except:
        print('Unable to round to')
        return x


def is_valid_reference(ref):
    """ Checks if reference is correct """
    references = 'first', 'average', 'experimental'
    return ref in references


def id():
    """Give the id of the object.
        """
    pass


def size_splitter(size, part_size):
    """Receive file size and return a list of size ranges"""
    result = []
    if size == 0:
        result.append('0-0')
        return result
    span = part_size if part_size <= size else size
    parts = max(size // span, 1)
    x = 0
    size = size - 1
    for i in range(parts):
        y = x + span - 1
        if size - y < span:
            y = size
        result.append(f'{x}-{y}')
        x = y + 1
    return result


def softsign(attrs, inputs, proto_obj):
    """Computes softsign of x element-wise."""
    return 'softsign', attrs, inputs


def array_1d(array):
    """
    Check if the given array has only one dimension. Following formats will
    return True:
        (x,), (x,1) and (1,x)
    """
    if not len(array.shape) == 1:
        if len(array.shape) == 2:
            if array.shape[0] == 1 or array.shape[1] == 1:
                return True
            else:
                raise ValueError('only 1D arrays are accepted')
    else:
        return True
    return True


def is_dict(obj):
    """Returns True if the object is a python dictionary.
    """
    return isinstance(obj, dict)


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


def unique(seq):
    """ Remove duplicates from the supplied sequence """
    dictionary = {}
    for i in seq:
        dictionary[i] = 1
    return list(dictionary.keys())


def empty_type_dict(input_object):
    """Generates an otherwise empty Python dict with the correct
    "type" key from Java.

    :param input_class: arbitrary instance of a Python class
    :return:
    """
    d = dict()
    d['type'] = input_object.__class__.__name__
    return d


@staticmethod
def parameters():
    """ Return parameters for this type of integral """
    raise NotImplementedError


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

        :param SharedContentRestoreInviteesType val:
        :rtype: EventType
        """
    return cls('shared_content_restore_invitees', val)


def detect_version(endpoint: str) ->str:
    """
    Detect the api version from endpoint url.
    Currently cachet only has a single "v1" endpoint but this may change in the future.
    """
    if endpoint.endswith('/v1'):
        return '1'
    raise ValueError(
        "Cannot determine api version based on endpoint '{}'. If the api version is not present in the url, please supply it on client creation."
        .format(endpoint))


def make_collocate_show(show, current):
    """
    Turn show into a collocate showing thing
    """
    out = []
    for i in show:
        out.append(i)
    for i in show:
        newn = '%s%s' % (str(current), i)
        if not newn.startswith('-'):
            newn = '+' + newn
        out.append(newn)
    return out


def for_real_scale(x):
    """
    Converts x to real scale using 10**(x/10)

    Parameters
    ---------
    x: int or float
        The value for convertion

    Returns
    -------
    float:
        The x value converted in eal scale.
    """
    return 10 ** (x / 10)


def has_resource(resource_name):
    """Does the package contain the named resource?"""


@classmethod
def from_share_link(cls, share_link):
    """Return a DNASequence based on its weblink.

        Weblink may be a share link or a url
        """
    return cls.get(cls.get_seq_id_from_link(share_link))


def _unpack_tuple(x):
    """ Unpacks one-element tuples for use as return values """
    if len(x) == 1:
        return x[0]
    else:
        return x


def join_authority(authority):
    """
       Reverse of split_authority()

       >>>join_authority(('user', 'password', 'host', 'port'))
       "user:password@host:port"

    """
    user, passwd, host, port = authority
    result = ''
    if user:
        result += user
        if passwd:
            result += ':' + passwd
        result += '@'
    result += host
    if port:
        result += ':' + port
    return result


def p_expr_parens(t):
    """expr : LPARENS expr RPARENS"""
    t[0] = t[2]


def get_sequencenumber(exif) ->int:
    """
    Return position of image within the recoding sequence.
    """
    try:
        return exif['SequenceNumber']['num']
    except KeyError:
        return 0


def default_key_func(key, key_prefix, version):
    """
    Default function to generate keys.

    Construct the key used by all other methods. By default, prepend
    the `key_prefix'. KEY_FUNCTION can be used to specify an alternate
    function with custom key making behavior.
    """
    return '%s:%s:%s' % (key_prefix, version, key)


@classmethod
def master(cls, cluster_id_label):
    """
        Show the details of the master of the cluster with id/label `cluster_id_label`.
        """
    cluster_status = cls.status(cluster_id_label)
    if cluster_status.get('state') == 'UP':
        return list(filter(lambda x: x['role'] == 'master', cluster_status.
            get('nodes')))[0]
    else:
        return cluster_status


def get_streaming_distribution(Id=None):
    """
    Gets information about a specified RTMP distribution, including the distribution configuration.
    See also: AWS API Documentation

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

    :type Id: string
    :param Id: [REQUIRED]
            The streaming distribution's ID.

    :rtype: dict
    :return: {
        'StreamingDistribution': {
            'Id': 'string',
            'ARN': 'string',
            'Status': 'string',
            'LastModifiedTime': datetime(2015, 1, 1),
            'DomainName': 'string',
            'ActiveTrustedSigners': {
                'Enabled': True|False,
                'Quantity': 123,
                'Items': [
                    {
                        'AwsAccountNumber': 'string',
                        'KeyPairIds': {
                            'Quantity': 123,
                            'Items': [
                                'string',
                            ]
                        }
                    },
                ]
            },
            'StreamingDistributionConfig': {
                'CallerReference': 'string',
                'S3Origin': {
                    'DomainName': 'string',
                    'OriginAccessIdentity': 'string'
                },
                'Aliases': {
                    'Quantity': 123,
                    'Items': [
                        'string',
                    ]
                },
                'Comment': 'string',
                'Logging': {
                    'Enabled': True|False,
                    'Bucket': 'string',
                    'Prefix': 'string'
                },
                'TrustedSigners': {
                    'Enabled': True|False,
                    'Quantity': 123,
                    'Items': [
                        'string',
                    ]
                },
                'PriceClass': 'PriceClass_100'|'PriceClass_200'|'PriceClass_All',
                'Enabled': True|False
            }
        },
        'ETag': 'string'
    }

    :returns:
    (string) --

    """
    pass


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

        :param EmmAddExceptionDetails val:
        :rtype: EventDetails
        """
    return cls('emm_add_exception_details', val)


def _fixencoding(input, encoding, final=False):
    """
    Replace the name of the encoding in the charset rule at the beginning of
    ``input`` with ``encoding``. If ``input`` doesn't starts with a charset
    rule, ``input`` will be returned unmodified.

    If the encoding can't be found yet, ``None`` is returned. ``final``
    specifies whether more data will be available in later calls or not.
    If ``final`` is true, ``_fixencoding()`` will never return ``None``.
    """
    prefix = '@charset "'
    if len(input) > len(prefix):
        if input.startswith(prefix):
            pos = input.find('"', len(prefix))
            if pos >= 0:
                if encoding.replace('_', '-').lower() == 'utf-8-sig':
                    encoding = 'utf-8'
                return prefix + encoding + input[pos:]
        else:
            return input
    elif not prefix.startswith(input) or final:
        return input
    if final:
        return input
    return None


def vert_connect():
    """Connect selected vertices of faces, splitting the face

    """
    pass


def select_more():
    """Select keyframes beside already selected ones

    """
    pass


@staticmethod
def matcher_stt(token, terminal, m):
    """ Check connective conjunction ('sem', 'er') """
    return m.ordfl == 'st' and m.stofn in {'sem', 'er'}


@staticmethod
def _negotiate_integer_value(client_value, server_value):
    """Negotiates two values. If either of them is 0 or None,
        returns the other one. If both are positive integers, returns the
        smallest one.

        :param int client_value: The client value
        :param int server_value: The server value
        :rtype: int

        """
    if client_value is None:
        client_value = 0
    if server_value is None:
        server_value = 0
    if client_value == 0 or server_value == 0:
        val = max(client_value, server_value)
    else:
        val = min(client_value, server_value)
    return val


def palettecolor_unlock_all():
    """Unlock all Grease Pencil colors so that they can be edited

    """
    pass