def read_summary(summary):
    """Parse GATK CallableLoci summary. Return dict."""
    d = dict()
    with open(summary, 'r') as f:
        next(f)
        for line in f:
            x, y = line.lstrip().split()
            d[x] = y
    return d


def p_gcl_end_projection(t):
    """gcl_expr : LCPAREN gcl_expr OP_END_PROJECTION"""
    t[0] = 'End', t[2]


def constrain(value, minv, maxv):
    """constrain a value to a range"""
    if value < minv:
        value = minv
    if value > maxv:
        value = maxv
    return value


def wrapSizeLimit(ctx, output_size, confidential=True, qop=None):
    """
    Calculates the Max Message Size

    This method calculates the maxium size that a message can be
    in order to have the wrapped message fit within the given size.

    :param ctx: the current security context
    :param int output_size: the desired maxiumum wrapped message size
    :param bool conf_req: whether or not encryption is to be used when
                          wrapping the message
    :param qop: the desired Quality of Protection (or None for default)
    :type qop: int or None
    :returns: the max unwrapped message size
    :rtype: int
    """


@classmethod
def from_seconds(cls, float_secs):
    """
        Use Time.from_sec() instead. Retained for backwards compatibility.

        @param float_secs: time value in time.time() format
        @type  float_secs: float
        @return: Time instance for specified time
        @rtype: L{Time}
        """
    return cls.from_sec(float_secs)


def reverse_dict(d):
    """Reverses direction of dependence dict

    >>> d = {'a': (1, 2), 'b': (2, 3), 'c':()}
    >>> reverse_dict(d)  # doctest: +SKIP
    {1: ('a',), 2: ('a', 'b'), 3: ('b',)}

    :note: dict order are not deterministic. As we iterate on the
        input dict, it make the output of this function depend on the
        dict order. So this function output order should be considered
        as undeterministic.

    """
    result = {}
    for key in d:
        for val in d[key]:
            result[val] = result.get(val, tuple()) + (key,)
    return result


def apply_transform(service, t, x):
    """Apply a transformation using `self` as object reference."""
    if t is None:
        return x
    else:
        return t(service, x)


@conf
def link_add_flags(conf):
    """
	Adds LINKFLAGS / LDFLAGS from os.environ to conf.env
	"""
    conf.add_os_flags('LINKFLAGS', dup=False)
    conf.add_os_flags('LDFLAGS', dup=False)


def formula(foyer_fiscal, period, parameters):
    """
        Réduction d'impôt au titre des enfants à charge poursuivant leurs études secondaires ou supérieures
        """
    f7ea = foyer_fiscal('f7ea', period)
    f7eb = foyer_fiscal('f7eb', period)
    f7ec = foyer_fiscal('f7ec', period)
    f7ed = foyer_fiscal('f7ed', period)
    f7ef = foyer_fiscal('f7ef', period)
    f7eg = foyer_fiscal('f7eg', period)
    P = parameters(period).impot_revenu.reductions_impots.ecpess
    return P.col * (f7ea + f7eb / 2) + P.lyc * (f7ec + f7ed / 2) + P.sup * (
        f7ef + f7eg / 2)


def address(addr):
    """
    A special argument type that splits a string on ':' and transforms
    the result into a tuple of host and (integer) port.
    """
    if ':' in addr:
        host, _sep, port = addr.rpartition(':')
        try:
            port = int(port)
        except ValueError:
            raise ValueError('invalid port number %r' % port)
        addr = host, port
    return addr


@classmethod
def _can_handle_query(cls, *query):
    """
        Answers whether client can service the query.

        Parameters
        ----------
        query : list of query objects

        Returns
        -------
        boolean
            answer as to whether client can service the query
        """
    for x in query:
        if x.__class__.__name__ == 'Instrument' and str(x.value).lower() in [
            'soon', 'srs_table']:
            return True
    return False


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

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

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


def permute_vector(rev_order, membership):
    """
	Rearrange community membership vector according to permutation

	Used to realign community vector output after node permutation.

	:param rev_order: new indices of each nodes
	:param membership: community membership vector to be rearranged
	:return: rearranged membership vector.
	"""
    new_member = [(-1) for i in range(len(rev_order))]
    for i, val in enumerate(rev_order):
        new_member[val] = membership[i]
    assert -1 not in new_member
    return new_member


@staticmethod
def do_quit(args):
    """
        Quits the program.
        """
    print('Quitting.')
    raise SystemExit


def provides(base):
    """Returns whether or not this extension can provide for the
        server."""
    version = base.basic_rfc.server_version[0]
    if version is None:
        return False
    elif version.startswith('charybdis'):
        return True
    return False


def convert_string_type(value):
    """Quick and dirty way to convert strings into their (guessed) original type.

    FileMaker Data API only returns strings. Hopefully, we can throw this function away as
    soon as the Data API is out of beta :-)

    Not used when running fmrest with default parameters as returned values can
    be unexpected.
    """
    for type_ in (int, float):
        try:
            return type_(value)
        except ValueError:
            pass
    try:
        from dateutil.parser import parse
        from datetime import timedelta
        parsed = parse(value)
        if '/' not in value:
            parsed = timedelta(hours=parsed.hour, minutes=parsed.minute,
                seconds=parsed.second)
        return parsed
    except ValueError:
        pass
    time_split = value.split(':')
    if len(time_split) == 3:
        try:
            hours = int(time_split[0])
            minutes = int(time_split[1])
            seconds = int(time_split[2])
            return timedelta(hours=hours, minutes=minutes, seconds=seconds)
        except ValueError:
            pass
    return value


def get(name):
    """
        Получить атрибут по имени.

        @param name: имя атрибута
        @type name: C{str}
        @return: атрибут
        @rtype: L{IAttribute}
        """


def p_struct_body(t):
    """struct_body : LBRACE declaration_list RBRACE"""
    t[0] = t[2]


def make_srmfile_from_step_results(prev_step_token_task, parent_dag=None):
    """Makes a list of srms using the results of all the tokens in a previous task
    """
    if not parent_dag:
        pass
    else:
        pass


@staticmethod
def _infnone(number):
    """
        Converts a Nonetype object to inf.

        :param number: (int/float/None) a number
        :return: (float) -inf or number
        """
    return float('-inf') if number is None else number


@staticmethod
def _get_workers_with_max_size(worker_to_size):
    """Get workers with maximal size"""
    max_workers = set()
    max_size = 0
    for w, size in worker_to_size.items():
        if size > max_size:
            max_size = size
            max_workers = {w}
        elif size == max_size:
            max_workers.add(w)
    max_workers.difference_update([None])
    return max_size, list(max_workers)


def put_bucket_lifecycle_configuration(Bucket=None, LifecycleConfiguration=None
    ):
    """
    Sets lifecycle configuration for your bucket. If a lifecycle configuration exists, it replaces it.
    See also: AWS API Documentation

    :example: response = client.put_bucket_lifecycle_configuration(
        Bucket='string',
        LifecycleConfiguration={
            'Rules': [
                {
                    'Expiration': {
                        'Date': datetime(2015, 1, 1),
                        'Days': 123,
                        'ExpiredObjectDeleteMarker': True|False
                    },
                    'ID': 'string',
                    'Prefix': 'string',
                    'Filter': {
                        'Prefix': 'string',
                        'Tag': {
                            'Key': 'string',
                            'Value': 'string'
                        },
                        'And': {
                            'Prefix': 'string',
                            'Tags': [
                                {
                                    'Key': 'string',
                                    'Value': 'string'
                                },
                            ]
                        }
                    },
                    'Status': 'Enabled'|'Disabled',
                    'Transitions': [
                        {
                            'Date': datetime(2015, 1, 1),
                            'Days': 123,
                            'StorageClass': 'GLACIER'|'STANDARD_IA'
                        },
                    ],
                    'NoncurrentVersionTransitions': [
                        {
                            'NoncurrentDays': 123,
                            'StorageClass': 'GLACIER'|'STANDARD_IA'
                        },
                    ],
                    'NoncurrentVersionExpiration': {
                        'NoncurrentDays': 123
                    },
                    'AbortIncompleteMultipartUpload': {
                        'DaysAfterInitiation': 123
                    }
                },
            ]
        }
    )

    :type Bucket: string
    :param Bucket: [REQUIRED]

    :type LifecycleConfiguration: dict
    :param LifecycleConfiguration:
            Rules (list) -- [REQUIRED]
            (dict) --
            Expiration (dict) --
            Date (datetime) -- Indicates at what date the object is to be moved or deleted. Should be in GMT ISO 8601 Format.
            Days (integer) -- Indicates the lifetime, in days, of the objects that are subject to the rule. The value must be a non-zero positive integer.
            ExpiredObjectDeleteMarker (boolean) -- Indicates whether Amazon S3 will remove a delete marker with no noncurrent versions. If set to true, the delete marker will be expired; if set to false the policy takes no action. This cannot be specified with Days or Date in a Lifecycle Expiration Policy.
            ID (string) -- Unique identifier for the rule. The value cannot be longer than 255 characters.
            Prefix (string) -- Prefix identifying one or more objects to which the rule applies. This is deprecated; use Filter instead.
            Filter (dict) -- The Filter is used to identify objects that a Lifecycle Rule applies to. A Filter must have exactly one of Prefix, Tag, or And specified.
            Prefix (string) -- Prefix identifying one or more objects to which the rule applies.
            Tag (dict) -- This tag must exist in the object's tag set in order for the rule to apply.
            Key (string) -- [REQUIRED] Name of the tag.
            Value (string) -- [REQUIRED] Value of the tag.
            And (dict) -- This is used in a Lifecycle Rule Filter to apply a logical AND to two or more predicates. The Lifecycle Rule will apply to any object matching all of the predicates configured inside the And operator.
            Prefix (string) --
            Tags (list) -- All of these tags must exist in the object's tag set in order for the rule to apply.
            (dict) --
            Key (string) -- [REQUIRED] Name of the tag.
            Value (string) -- [REQUIRED] Value of the tag.

            Status (string) -- [REQUIRED] If 'Enabled', the rule is currently being applied. If 'Disabled', the rule is not currently being applied.
            Transitions (list) --
            (dict) --
            Date (datetime) -- Indicates at what date the object is to be moved or deleted. Should be in GMT ISO 8601 Format.
            Days (integer) -- Indicates the lifetime, in days, of the objects that are subject to the rule. The value must be a non-zero positive integer.
            StorageClass (string) -- The class of storage used to store the object.

            NoncurrentVersionTransitions (list) --
            (dict) -- Container for the transition rule that describes when noncurrent objects transition to the STANDARD_IA or GLACIER storage class. If your bucket is versioning-enabled (or versioning is suspended), you can set this action to request that Amazon S3 transition noncurrent object versions to the STANDARD_IA or GLACIER storage class at a specific period in the object's lifetime.
            NoncurrentDays (integer) -- Specifies the number of days an object is noncurrent before Amazon S3 can perform the associated action. For information about the noncurrent days calculations, see How Amazon S3 Calculates When an Object Became Noncurrent in the Amazon Simple Storage Service Developer Guide.
            StorageClass (string) -- The class of storage used to store the object.

            NoncurrentVersionExpiration (dict) -- Specifies when noncurrent object versions expire. Upon expiration, Amazon S3 permanently deletes the noncurrent object versions. You set this lifecycle configuration action on a bucket that has versioning enabled (or suspended) to request that Amazon S3 delete noncurrent object versions at a specific period in the object's lifetime.
            NoncurrentDays (integer) -- Specifies the number of days an object is noncurrent before Amazon S3 can perform the associated action. For information about the noncurrent days calculations, see How Amazon S3 Calculates When an Object Became Noncurrent in the Amazon Simple Storage Service Developer Guide.
            AbortIncompleteMultipartUpload (dict) -- Specifies the days since the initiation of an Incomplete Multipart Upload that Lifecycle will wait before permanently removing all parts of the upload.
            DaysAfterInitiation (integer) -- Indicates the number of days that must pass since initiation for Lifecycle to abort an Incomplete Multipart Upload.

    """
    pass


@classmethod
def patch(cls, patch_ob_list):
    """
        Raw patch function. See also `save_all`, `update_all`, and `remove_all`
        :param patch_ob_list: Posted as `{"requests":patch_ob_list}`
        :return: List of separate response object containing `success` or `error` attr
        """
    return cls._patch_avos(patch_ob_list)


def without_fixed_prefix(form, prefix_length):
    """ Return a new form with ``prefix_length`` chars removed from left """
    word, tag, normal_form, score, methods_stack = form
    return word[prefix_length:], tag, normal_form[prefix_length:
        ], score, methods_stack


@classmethod
def fromkeys(cls, iterable, value=None):
    """OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S
        and values equal to v (which defaults to None).

        """
    d = cls()
    for key in iterable:
        d[key] = value
    return d


def shorten_text(txt, before, after, placeholder='...'):
    """Shorten a text to max before+len(placeholder)+after chars.

    The new text will keep the before first characters and after last characters
    """
    if len(txt) <= before + len(placeholder) + after:
        return txt
    else:
        return txt[:before] + placeholder + txt[-after:]


def _default_key_normalizer(key_class, request_context):
    """
    Create a pool key out of a request context dictionary.

    According to RFC 3986, both the scheme and host are case-insensitive.
    Therefore, this function normalizes both before constructing the pool
    key for an HTTPS request. If you wish to change this behaviour, provide
    alternate callables to ``key_fn_by_scheme``.

    :param key_class:
        The class to use when constructing the key. This should be a namedtuple
        with the ``scheme`` and ``host`` keys at a minimum.
    :type  key_class: namedtuple
    :param request_context:
        A dictionary-like object that contain the context for a request.
    :type  request_context: dict

    :return: A namedtuple that can be used as a connection pool key.
    :rtype:  PoolKey
    """
    context = request_context.copy()
    context['scheme'] = context['scheme'].lower()
    context['host'] = context['host'].lower()
    for key in ('headers', '_proxy_headers', '_socks_options'):
        if key in context and context[key] is not None:
            context[key] = frozenset(context[key].items())
    socket_opts = context.get('socket_options')
    if socket_opts is not None:
        context['socket_options'] = tuple(socket_opts)
    for key in list(context.keys()):
        context['key_' + key] = context.pop(key)
    for field in key_class._fields:
        if field not in context:
            context[field] = None
    return key_class(**context)


def _pipe_segment_with_colons(align, colwidth):
    """Return a segment of a horizontal line with optional colons which
    indicate column's alignment (as in `pipe` output format)."""
    w = colwidth
    if align in ['right', 'decimal']:
        return '-' * (w - 1) + ':'
    elif align == 'center':
        return ':' + '-' * (w - 2) + ':'
    elif align == 'left':
        return ':' + '-' * (w - 1)
    else:
        return '-' * w


def iter_lanes(points):
    """
    Loop through collection of numbers (points) and yield
    the sequential groupings. Any gap in the sequence will
    produce a new grouping

    for example this sequence:

        [1, 2, 3, 7, 8, 9, 12, 13, 14]

    with yield:

        ((1, 2, 3), (7, 8, 9), (12, 13, 14))

    """
    last = -5
    lane = []
    for pt in points:
        if pt == last + 1:
            lane.append(pt)
        else:
            if lane:
                yield lane
            lane = [pt]
        last = pt
    yield lane


def dbh_data_table(path, contenttype, extension, roottag, nsurl):
    """ Data Table Handler - Returns data_table for all tbl files """
    if extension == 'tbl':
        return 'db_data_table'
    else:
        return False


def get_app_qt4(*args, **kwargs):
    """Create a new qt4 app or return an existing one."""
    from PyQt4 import QtWidgets
    app = QtWidgets.QApplication.instance()
    if app is None:
        if not args:
            args = [''],
        app = QtWidgets.QApplication(*args, **kwargs)
    return app


def _ip_range_splitter(ips, block_size=256):
    """Yields blocks of IPs no more than block_size elements long."""
    out = []
    count = 0
    for ip in ips:
        out.append(ip['address'])
        count += 1
        if count > block_size - 1:
            yield out
            out = []
            count = 0
    if out:
        yield out


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 p_phrase_or_term(p):
    """phrase_or_term : TERM
                      | PHRASE"""
    p[0] = p[1]


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

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

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


def context_modal_mouse(data_path_iter: str='', data_path_item: str='',
    header_text: str='', input_scale: float=0.01, invert: bool=False,
    initial_x: int=0):
    """Adjust arbitrary values with mouse input

    :param data_path_iter: data_path_iter, The data path relative to the context, must point to an iterable
    :type data_path_iter: str
    :param data_path_item: data_path_item, The data path from each iterable to the value (int or float)
    :type data_path_item: str
    :param header_text: Header Text, Text to display in header during scale
    :type header_text: str
    :param input_scale: input_scale, Scale the mouse movement by this value before applying the delta
    :type input_scale: float
    :param invert: invert, Invert the mouse input
    :type invert: bool
    :param initial_x: initial_x
    :type initial_x: int
    """
    pass


def p_equiv_member(parser):
    """
    equiv_member : id
    """
    parser[0] = '%s' % (parser[1],)
    return parser


def search_phrase(phrase):
    """Execute a search on a phrase given as a string.

        Return an IFBtree mapping docid to score.
        """


def urljoin(*args):
    """Joins given arguments into an URL.

    Trailing, but not leading slashes are stripped for each argument.
    """
    return '/'.join(map(lambda x: str(x).rstrip('/'), args))


@property
def __members__(cls):
    """Returns a mapping of member name->value.

        This mapping lists all enum members, including aliases. Note that this
        is a copy of the internal mapping.

        """
    return cls._member_map_.copy()


@staticmethod
def get_token_from_file(file):
    """Opens a file and returns its content (plaintext)

        Parameters
        -----------
        file: :class:`str`
            The file the token is in. Best if the file is plaintext.

        Returns
        -----------
        token: :class:`str`
            The file's content (should be a token)
        """
    with open(file, 'r') as f:
        token = f.read()
    return token


def save_to_disk(obj, fname, **dump_opts):
    """Save an object to disk using joblib.dump.
    """
    import joblib
    return joblib.dump(obj, fname, **dump_opts)


def to_bytes(seq):
    """convert a sequence to a bytes type"""
    if isinstance(seq, bytes):
        return seq
    elif isinstance(seq, bytearray):
        return bytes(seq)
    elif isinstance(seq, memoryview):
        return seq.tobytes()
    else:
        b = bytearray()
        for item in seq:
            b.append(item)
        return bytes(b)


def psi_Mg_MgOH_CO3_HMW84(T, P):
    """c-c'-a: magnesium magnesium-hydroxide carbonate [HMW84]."""
    psi = 0.0
    valid = T == 298.15
    return psi, valid


def clip_norm(g, c, n):
    """Ref: https://github.com/keras-team/keras/blob/7a39b6c62d43c25472b2c2476bd2a8983ae4f682/keras/optimizers.py#L21
    Clip the gradient `g` if the L2 norm `n` exceeds `c`.
    =====================================================
    @param  g: (ndarray) Gradient.
    @param  c: (float)   Gradients will be clipped when their L2 norm exceeds this value.
    @param  n: (ndarray) Actual norm of `g`
    @return g: (ndarray) Gradient clipped if required.
    """
    if c <= 0 or n < c:
        return g
    else:
        return c / n * g


def chmsg(event, server, view):
    """ Everytime someone types on a channel this method is called
        It gets the channel name and the win(that one which we have added in the ujoin event.
        It gets the window with the same method server.getName.
    """
    ch = event['channel'].lower()
    win = view.get_win((server.getName(), ch))
    nicka = event['nicka']
    msg = event['msg']
    packet = '<%s>%s\n' % (nicka, msg)
    win.update_screen(packet)


def get_samples(template_id):
    """Get samples for a given template.

        Returns a dictionary with sample inputs.

        keys are the unique ids for the sample inputs.
        values are the actual template-language native data structures.
        """


def autoconfig_not_implemented():
    """
    This feature is not implemented

    """
    print('\nThis Feature is not implemented yet....')


def format_headers(headers):
    """
    Formats to a dictionary of headers
    names and column index

    {'data': [{'name': 'column_name', 'column_index': int}]}

    :param headers: Column object
    :return: header data as a dictionary object
    """
    if type(headers) is not list:
        _headers = list(headers)
    _headers = headers
    header_data = {'data': []}
    column_index = 0
    for key in _headers:
        header_data['data'].append({'name': key[0], 'column_index':
            column_index})
        column_index += 1
    return header_data


def is_s(c):
    """Tests production [3] S

    Optimized for speed as this function is called a lot by the parser."""
    return c is not None and c in ' \t\n\r'


def rtrimTerminus(command, terminator=None):
    """Return command minus anything that follows the final terminator."""
    if terminator:
        pieces = command.split(terminator)
        if len(pieces) > 1:
            command = terminator.join(pieces[:-1]) + terminator
    return command


@staticmethod
def set_absolute_end_of_labels(label_list):
    """
        If there are any labels where the end is defined as -1 (end of utterance),
        set the concrete time.

        Arguments:
            label_list (LabelList): The label-list to process.
        """
    for label in sorted(label_list, key=lambda x: x.start):
        if label.end <= label.start:
            raise ValueError('Label-end {} is smaller than label-start {}!'
                .format(label.end, label.start))
        if label.value is not '###############':
            if label.end == -1:
                label.end = label.label_list.utterance.end
            if label.end == -1:
                label.end = (label.label_list.utterance.file.duration -
                    label.label_list.utterance.start)
    return label_list


def validate_string_type(s, f, l1, l2):
    """
    Field must be string type
    """
    if type(s) is not str:
        raise Exception('%s %s for %s %s must be string type. Type is %s' %
            (l1, s, l2, f, type(s)))


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 is_youtube(raw_song):
    """ Check if the input song is a YouTube link. """
    status = len(raw_song) == 11 and raw_song.replace(' ', '%20') == raw_song
    status = status and not raw_song.lower() == raw_song
    status = status or 'youtube.com/watch?v=' in raw_song
    return status


def disable_logs():
    """
    Clear _LogsEnabled flag, so calls to ``log()`` and ``exc()`` will do
    nothing.

    Must be used in production release to increase performance. However
    I plan to comment all lines with ``lg.log()`` at all.
    """
    global _LogsEnabled
    _LogsEnabled = False


def setup_platform(hass, config, add_entities, discovery_info=None):
    """Set up the iOS sensor."""


def remove_prefix(text, prefix):
    """ remove prefix from text
    """
    if text.startswith(prefix):
        return text[len(prefix):]
    return text


def hold_commit_lock(cursor, ensure_current=True, nowait=False):
    """
        Acquire the commit lock.

        If *ensure_current* is True (the default), other tables may be
        locked as well, to ensure the most current data is available.
        When using row level locks, *ensure_current* is always
        implicit.

        With *nowait* set to True, only try to obtain the lock without
        waiting and return a boolean indicating if the lock was
        successful. **Note:** this parameter is deprecated and will be removed
        in the future; it is not currently used.

        Should raise `UnableToAcquireCommitLockError` if the lock can not
        be acquired before a configured timeout.
        """


def _coerce_vary_rounds(value):
    """parse vary_rounds string to percent as [0,1) float, or integer"""
    if value.endswith('%'):
        return float(value.rstrip('%')) * 0.01
    try:
        return int(value)
    except ValueError:
        return float(value)


def normalize(num, lower=0, upper=360, b=False):
    """Normalize number to range [lower, upper) or [lower, upper].

    Parameters
    ----------
    num : float
        The number to be normalized.
    lower : int
        Lower limit of range. Default is 0.
    upper : int
        Upper limit of range. Default is 360.
    b : bool
        Type of normalization. Default is False. See notes.

    Returns
    -------
    n : float
        A number in the range [lower, upper) or [lower, upper].

    Raises
    ------
    ValueError
      If lower >= upper.

    Notes
    -----
    If the keyword `b == False`, then the normalization is done in the
    following way. Consider the numbers to be arranged in a circle,
    with the lower and upper ends sitting on top of each other. Moving
    past one limit, takes the number into the beginning of the other
    end. For example, if range is [0 - 360), then 361 becomes 1 and 360
    becomes 0. Negative numbers move from higher to lower numbers. So,
    -1 normalized to [0 - 360) becomes 359.

    If the keyword `b == True`, then the given number is considered to
    "bounce" between the two limits. So, -91 normalized to [-90, 90],
    becomes -89, instead of 89. In this case the range is [lower,
    upper]. This code is based on the function `fmt_delta` of `TPM`.

    Range must be symmetric about 0 or lower == 0.

    Examples
    --------
    >>> normalize(-270,-180,180)
    90.0
    >>> import math
    >>> math.degrees(normalize(-2*math.pi,-math.pi,math.pi))
    0.0
    >>> normalize(-180, -180, 180)
    -180.0
    >>> normalize(180, -180, 180)
    -180.0
    >>> normalize(180, -180, 180, b=True)
    180.0
    >>> normalize(181,-180,180)
    -179.0
    >>> normalize(181, -180, 180, b=True)
    179.0
    >>> normalize(-180,0,360)
    180.0
    >>> normalize(36,0,24)
    12.0
    >>> normalize(368.5,-180,180)
    8.5
    >>> normalize(-100, -90, 90)
    80.0
    >>> normalize(-100, -90, 90, b=True)
    -80.0
    >>> normalize(100, -90, 90, b=True)
    80.0
    >>> normalize(181, -90, 90, b=True)
    -1.0
    >>> normalize(270, -90, 90, b=True)
    -90.0
    >>> normalize(271, -90, 90, b=True)
    -89.0
    """
    from math import floor, ceil
    res = num
    if not b:
        if lower >= upper:
            raise ValueError('Invalid lower and upper limits: (%s, %s)' % (
                lower, upper))
        res = num
        if num > upper or num == lower:
            num = lower + abs(num + upper) % (abs(lower) + abs(upper))
        if num < lower or num == upper:
            num = upper - abs(num - lower) % (abs(lower) + abs(upper))
        res = lower if num == upper else num
    else:
        total_length = abs(lower) + abs(upper)
        if num < -total_length:
            num += ceil(num / (-2 * total_length)) * 2 * total_length
        if num > total_length:
            num -= floor(num / (2 * total_length)) * 2 * total_length
        if num > upper:
            num = total_length - num
        if num < lower:
            num = -total_length - num
        res = num
    res *= 1.0
    return res


def query_to_dict(results, descriptions):
    """
    Replacement method for cursor.dictfetchall() as that method no longer
    exists in psycopg2, and I'm guessing in other backends too.

    Converts the results of a raw SQL query into a list of dictionaries, suitable
    for use in templates etc.
    """
    output = []
    for data in results:
        row = {}
        i = 0
        for column in descriptions:
            row[column[0]] = data[i]
            i += 1
        output.append(row)
    return output


def strip_geocoding(dicts):
    """
    Remove unwanted metadata from socrata location field
    """
    for record in dicts:
        try:
            location = record.get('location')
            record['location'] = {'latitude': location['latitude'],
                'longitutde': location['longitutde']}
        except KeyError:
            continue
    return dicts


def split(iterable, **split_options):
    """Perform a split on iterable.

    This method is highly inspired in the `iter` global method (in conjunction
    with its __iter__ counterpart method) for iterable classes.

    :param iterable: An iterable, which will typically be a Storage<Collection>
    :param split_options: The optional additional arguments to the split method.
    May be ignored.
    :return: A collection of Split, or something similar. If iterable is not a
    Storage<Collection>, returns a tuple with a single element, the iterable
    argument itself
    """
    try:
        return iterable.split(**split_options)
    except AttributeError:
        return iterable,


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


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 get_moment(data, n):
    """
    Compute the *n* moment of the data list *data*.

    Parameters
    ----------
    data: list
        Data to take the moment of.
    n: int
        Moment number.

    Returns
    -------
    float
        *n* moment of the data.
    """
    N = len(data)
    m_n = 0
    for x in data:
        m_n += x ** n
    m_n /= N
    return m_n


def _get_area_hash(area):
    """Calculate a (close to) unique hash value for a given area.
    """
    try:
        return hash(area.lons.tostring() + area.lats.tostring())
    except AttributeError:
        try:
            return hash(area.tostring())
        except AttributeError:
            return hash(str(area))


def value(iterable, key=None, position=1):
    """Generic value getter. Returns containing value."""
    if key is None:
        if hasattr(iterable, '__iter__'):
            return iterable[position]
        else:
            return iterable
    else:
        return iterable[key]


def checkrange(value, lo, hi, msg=''):
    """Check value for membership; raise ValueError if fails."""
    if value < lo or value > hi:
        raise ValueError(f'ERROR {msg}: {value} should be in range {lo} {hi}')


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 merge_dicts(*dict_args):
    """
    Given any number of dicts, shallow copy and merge into a new dict,
    precedence goes to key value pairs in latter dicts.
    """
    result = {}
    for dictionary in dict_args:
        result.update(dictionary)
    return result


def enter_critical_phase_until_transaction_end(connection, cursor):
    """
        Given a connection and cursor opened by this driver, cause it
        to attempt to raise its priority and return results faster.

        This mostly has meaning for gevent drivers, which may limit
        the amount of time they spend in the hub and the number of context
        switches to other greenlets.

        This phase continues until *after* the ultimate call that
        commits or aborts is sent, but should revert to normal as quickly as
        possible after that. :class:`IRelStorageAdapter` may cooperate with
        the driver using implementation-specific methods to end the phase
        at an appropriate time if there is a hidden commit.

        This method must be idempotent (have the same effect if called more than
        once) within a given transaction.
        """


def key():
    """
        Ключ домена. Уникальное и постоянное свойство
        каждого домена.

        @return: ключ домена
        @rtype: C{str}
        """


@staticmethod
def format_data(data):
    """Overridable function to format data for the template"""
    return data


def delete_deployment_group(applicationName=None, deploymentGroupName=None):
    """
    Deletes a deployment group.
    See also: AWS API Documentation

    :example: response = client.delete_deployment_group(
        applicationName='string',
        deploymentGroupName='string'
    )

    :type applicationName: string
    :param applicationName: [REQUIRED]
            The name of an AWS CodeDeploy application associated with the applicable IAM user or AWS account.

    :type deploymentGroupName: string
    :param deploymentGroupName: [REQUIRED]
            The name of an existing deployment group for the specified application.

    :rtype: dict
    :return: {
        'hooksNotCleanedUp': [
            {
                'name': 'string',
                'hook': 'string'
            },
        ]
    }

    """
    pass


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 label(client=None, deactivate=None, tag=None):
    """
    Makes label agent or label expression.

    ..  container:: example

        Labels logical ties with start offsets:

        >>> staff = abjad.Staff(r"\\times 2/3 { c'4 d'4 e'4 ~ } e'4 ef'4")
        >>> abjad.label(staff).with_start_offsets(direction=abjad.Up)
        Duration(1, 1)

        >>> abjad.override(staff).text_script.staff_padding = 4
        >>> abjad.override(staff).tuplet_bracket.staff_padding = 0
        >>> abjad.show(staff) # doctest: +SKIP

        ..  docs::

            >>> abjad.f(staff)
            \\new Staff
            \\with
            {
                \\override TextScript.staff-padding = #4
                \\override TupletBracket.staff-padding = #0
            }
            {
                \\times 2/3 {
                    c'4
                    ^ \\markup { 0 }
                    d'4
                    ^ \\markup { 1/6 }
                    e'4
                    ^ \\markup { 1/3 }
                    ~
                }
                e'4
                ef'4
                ^ \\markup { 3/4 }
            }

        See the ``Label`` API entry for many more examples.

    ..  container:: example expression

        Initializes positionally:

        >>> expression = abjad.label()
        >>> expression(staff)
        Label(client=<Staff{3}>)

        Initializes from keyword:

        >>> expression = abjad.label()
        >>> expression(client=staff)
        Label(client=<Staff{3}>)

        Makes label expression:

            >>> expression = abjad.label()
            >>> expression = expression.with_start_offsets()

        >>> staff = abjad.Staff(r"\\times 2/3 { c'4 d'4 e'4 ~ } e'4 ef'4")
        >>> expression(staff)
        Duration(1, 1)

        >>> abjad.override(staff).text_script.staff_padding = 4
        >>> abjad.override(staff).tuplet_bracket.staff_padding = 0
        >>> abjad.show(staff) # doctest: +SKIP

        ..  docs::

            >>> abjad.f(staff)
            \\new Staff
            \\with
            {
                \\override TextScript.staff-padding = #4
                \\override TupletBracket.staff-padding = #0
            }
            {
                \\times 2/3 {
                    c'4
                    ^ \\markup { 0 }
                    d'4
                    ^ \\markup { 1/6 }
                    e'4
                    ^ \\markup { 1/3 }
                    ~
                }
                e'4
                ef'4
                ^ \\markup { 3/4 }
            }

        See the ``Label`` API entry for many more examples.

    Returns label agent when ``client`` is not none.

    Returns label expression when ``client`` is none.
    """
    import abjad
    if client is not None:
        return abjad.Label(client=client, deactivate=deactivate, tag=tag)
    expression = abjad.Expression()
    expression = expression.label(tag=tag)
    return expression


def cnt_split(tar_list, cnt_per_slice):
    """
    Yield successive n-sized(cnt_per_slice) chunks from l(tar_list).

        >>> x = list(range(34))
        >>> for i in cnt_split(x, 5):
        >>>     print(i)
        <<< print result ...
        <<< [0, 1, 2, 3, 4]
        <<< [5, 6, 7, 8, 9]
        <<< [10, 11, 12, 13, 14]
        <<< [15, 16, 17, 18, 19]
        <<< [20, 21, 22, 23, 24]
        <<< [25, 26, 27, 28, 29]
        <<< [30, 31, 32, 33]

    The targetlist can be split into slices with a NAX size of 'cnt_per_slice' ...
    :param tar_list: target list to split
    :param cnt_per_slice: slice per max size...
    :return: yield one result.
    """
    for i in range(0, len(tar_list), cnt_per_slice):
        yield tar_list[i:i + cnt_per_slice]


def view_lock_to_active():
    """Lock the view to the active object/bone

    """
    pass


def evacdiff(atoms):
    """Calculate vacuum energy level difference from the dipole moment of
    a slab assumed to be in the xy plane

    Returns
    -------
    out: float
        vacuum level difference in eV
    """
    import numpy as np
    from ase.units import Bohr, Hartree
    A = np.linalg.det(atoms.cell[:2, :2] / Bohr)
    dipz = atoms.get_dipole_moment()[2] / Bohr
    evacsplit = 4 * np.pi * dipz / A * Hartree
    return evacsplit


def get_model_constants(model_settings):
    """
    Read constants from model settings file

    Returns
    -------
    constants : dict
        dictionary of constants to add to locals for use by expressions in model spec
    """
    return model_settings.get('CONSTANTS', {})


def factorized_quadratic(x, weights):
    """A factorized quadratic interaction.

    :param x:
        shape ``(batch_size, in_features)``
    :param weights:
        shape ``(n_factors, in_features, out_features)``
    """
    x = x[None, ...]
    res = (x @ weights) ** 2.0 - x ** 2.0 @ weights ** 2.0
    res = res.sum(dim=0)
    return 0.5 * res


def _get_scroll_id(results):
    """Get the scroll id from results
    """
    if '_scroll_id' in results:
        return results.split('"')[3]
    return None


def drop_where_all_empty(df):
    """
    Drop rows and columns which are completely empty.

    Parameters
    ----------
    df : :class:`pandas.DataFrame` | :class:`pandas.Series`
        Pandas object to ensure is in the form of a series.
    """
    for ix in range(len(df.axes)):
        df = df.dropna(how='all', axis=ix)
    return df


def activate_foreign_keys(sender, connection, **kwargs):
    """Enable integrity constraint with sqlite.
    """
    if connection.vendor == 'sqlite':
        cursor = connection.cursor()
        cursor.execute('PRAGMA foreign_keys = ON;')


def set_active_clip():
    """Undocumented contribute <https://developer.blender.org/T51061>

    """
    pass


def _f2s(v):
    """convert float to string without scientific notation"""
    s, sep, e = str(v).partition('e')
    a, sep, b = s.partition('.')
    pos = len(a) + int(e or 0)
    s = (a + b).rstrip('0')
    if pos >= len(s):
        return s.ljust(pos, '0')
    elif pos <= 0:
        return '0.' + '0' * -pos + s
    else:
        return s[:pos] + '.' + s[pos:]


def caller_module(level=2, sys=sys):
    """This function is taken from Pyramid Web Framework - ``pyramid.path.caller_module``."""
    module_globals = sys._getframe(level).f_globals
    module_name = module_globals.get('__name__') or '__main__'
    module = sys.modules[module_name]
    return module


def pytest_benchmark_update_json(config, benchmarks, output_json):
    """
    Use this to add custom fields in the output JSON.

    Example:

    .. sourcecode:: python

        def pytest_benchmark_update_json(config, benchmarks, output_json):
            output_json['foo'] = 'bar'
    """
    pass


def subpart_option(buildout, part, subpart, option, default=''):
    """Get an option for a filestorage subpart, falling back to the main part.
    """
    parts_to_check = ['%s_%s' % (part, subpart), part]
    val = default
    for p in parts_to_check:
        if p not in buildout:
            continue
        if option in buildout[p]:
            val = buildout[p][option]
            break
    return val % dict(fs_part_name=subpart)


def get_pager_start(pager, start):
    """Return the string for paging files with an offset.

    This is the '+N' argument which less and more (under Unix) accept.
    """
    if pager in ['less', 'more']:
        if start:
            start_string = '+' + str(start)
        else:
            start_string = ''
    else:
        start_string = ''
    return start_string


@classmethod
def format_file_header(cls, file_head_desc):
    """Generate a file header"""
    bytes = bytearray([cls.header_type_by_desc['file'], 0, cls.
        data_version_major, cls.data_version_minor, 0, 0, 0, 0])
    return bytes


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


def getRulesets():
    """Return the list of all registered rulesets."""


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


@staticmethod
def resource_to_html(resource):
    """
        Returns `resource` wrapped in the appropriate html tag for it's mimetype.
        """
    if resource.mimetype == 'text/css':
        if resource.kind == 'text':
            return u"<style type='text/css'>\n%s\n</style>" % resource.data
        if resource.kind == 'url':
            return (u"<link rel='stylesheet' href='%s' type='text/css'>" %
                resource.data)
        raise Exception('Unrecognized resource kind %r' % resource.kind)
    if resource.mimetype == 'application/javascript':
        if resource.kind == 'text':
            return u'<script>\n%s\n</script>' % resource.data
        if resource.kind == 'url':
            return (
                u"<script src='%s' type='application/javascript'></script>" %
                resource.data)
        raise Exception('Unrecognized resource kind %r' % resource.kind)
    if resource.mimetype == 'text/html':
        assert resource.kind == 'text'
        return resource.data
    raise Exception('Unrecognized mimetype %r' % resource.mimetype)


def describe_resource_groups(resourceGroupArns=None):
    """
    Describes the resource groups that are specified by the ARNs of the resource groups.
    See also: AWS API Documentation

    Examples
    Describes the resource groups that are specified by the ARNs of the resource groups.
    Expected Output:

    :example: response = client.describe_resource_groups(
        resourceGroupArns=[
            'string',
        ]
    )

    :type resourceGroupArns: list
    :param resourceGroupArns: [REQUIRED]
            The ARN that specifies the resource group that you want to describe.
            (string) --

    :rtype: dict
    :return: {
        'resourceGroups': [
            {
                'arn': 'string',
                'tags': [
                    {
                        'key': 'string',
                        'value': 'string'
                    },
                ],
                'createdAt': datetime(2015, 1, 1)
            },
        ],
        'failedItems': {
            'string': {
                'failureCode': 'INVALID_ARN'|'DUPLICATE_ARN'|'ITEM_DOES_NOT_EXIST'|'ACCESS_DENIED'|'LIMIT_EXCEEDED'|'INTERNAL_ERROR',
                'retryable': True|False
            }
        }
    }

    """
    pass


def checkNull(df, columnName, acceptableAmount):
    """

     # Run QA checks to confirm data population
    isNameValid = checkNull(df,'full_name',.9)
    isAgeValid = checkNull(df,'age',.9)
    isGenderValid = checkNull(df,'gender',1)

    :param df:
    :param columnName:
    :param acceptableAmount:
    :return:
    """
    acceptableQuality = False
    nullPercent = df[columnName].isnull().sum() / df[columnName].count()
    if nullPercent >= acceptableAmount:
        acceptableQuality = True
    return acceptableQuality


def _delete(subs, shared):
    """Configure the `doorstop delete` subparser."""
    info = 'delete a document directory'
    sub = subs.add_parser('delete', description=info.capitalize() + '.',
        help=info, **shared)
    sub.add_argument('prefix', help='prefix of document to delete')


def train_xgb(params, dtrain, bst=None, **kwargs):
    """ Train a XGBoost model """
    if bst is None:
        pass
    else:
        pass


@classmethod
def __format_comparison_line(cls, name, private, total):
    """
        Method to create the string that will be printed out to screen for the stats file.
        :return:
        """
    if total > 0:
        perc = 100 * private / total
    else:
        perc = 0
    string = '{0} {1}/{2}  ({3:.2f}%)'.format(cls.__format_rowname(name),
        private, total, perc)
    return string


def get(key, force_reload=False):
    """Return item with key or None.

        If force_reload is True, try to delete object with key from cache and
        return None.
        """


def Emax(calc, val):
    """https://www.quantum-espresso.org/Doc/INPUT_PROJWFC.html#emax
    """
    assert isinstance(val, (float, int))
    efermi = calc.get_fermi_level()
    if efermi is not None:
        return val + efermi


@classmethod
def parse(cls, name, data_size, reader, parsers):
    """given a 4 byte name, data_size int, BitstreamReader
        and dict of {"atom":handler} sub-parsers,
        returns an atom of this class"""
    assert name == b'data'
    return cls(*reader.parse('64p 16p 16u 16u 16p'))


def _simplify_cols_and_drop(df, col):
    """ Function to merge similar columns together and drop original columns. """
    cols = df.columns[df.columns.str.contains(col)]
    df[col] = df.lookup(df.index, df[cols].notnull().idxmax(axis=1))
    df.drop(cols, axis=1, inplace=True)
    return df


@classmethod
def from_evt(cls, evt):
    """
        Initializes a new instance of given class by copying all data.

        Args:
            evt: pero.MouseEvt
                Source event from which to copy the data.

        Returns:
            cls instance
                New instance of requested class.
        """
    return cls(native=evt.native, view=evt.view, control=evt.control, x_pos
        =evt.x_pos, y_pos=evt.y_pos, x_rot=evt.x_rot, y_rot=evt.y_rot,
        left_down=evt.left_down, middle_down=evt.middle_down, right_down=
        evt.right_down, alt_down=evt.alt_down, cmd_down=evt.cmd_down,
        ctrl_down=evt.ctrl_down, shift_down=evt.shift_down)


def isdir():
    """
        Returns True if the asset is a directory, otherwise returns False.
        """


def round_ste(data=None, out=None, name=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 : NDArray
        The input array.

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

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


def firstOf(coll):
    """
    Provides the first element from the provided collection.

    @param coll: list|tuple|iterable
        The collection to provide the first item.
    """
    if isinstance(coll, (list, tuple)):
        return coll[0]
    coll = iter(coll)
    return next(coll)


@classmethod
def fromJob(cls, job, command, predecessorNumber):
    """
        Build a job node from a job object
        :param toil.job.Job job: the job object to be transformed into a job node
        :param str command: the JobNode's command
        :param int predecessorNumber: the number of predecessors that must finish
            successfully before the job can be scheduled
        :return: a JobNode object representing the job object parameter
        :rtype: toil.job.JobNode
        """
    return cls(jobStoreID=None, requirements=job._requirements, command=
        command, jobName=job.jobName, unitName=job.unitName, displayName=
        job.displayName, predecessorNumber=predecessorNumber)


def get_coord_labels(df):
    """Retrieve the coordinate labels from df.

    Parameters
    ----------
    df : pd.DataFrame
        DataFrame with each row being a geo location and two columns
        containing coordinate labels.

    Returns
    -------
    df_coord_labels : list | None
        Two entry list if coordinate labels are found:
        ['lat', 'lon'] or ['latitude', 'longitude']
    """
    df_coord_labels = None
    if 'lat' in df and 'lon' in df:
        df_coord_labels = ['lat', 'lon']
    elif 'latitude' in df and 'longitude' in df:
        df_coord_labels = ['latitude', 'longitude']
    return df_coord_labels


def describe_instance_status(DryRun=None, InstanceIds=None, Filters=None,
    NextToken=None, MaxResults=None, IncludeAllInstances=None):
    """
    Describes the status of one or more instances. By default, only running instances are described, unless specified otherwise.
    Instance status includes the following components:
    See also: AWS API Documentation

    :example: response = client.describe_instance_status(
        DryRun=True|False,
        InstanceIds=[
            'string',
        ],
        Filters=[
            {
                'Name': 'string',
                'Values': [
                    'string',
                ]
            },
        ],
        NextToken='string',
        MaxResults=123,
        IncludeAllInstances=True|False
    )

    :type DryRun: boolean
    :param DryRun: Checks whether you have the required permissions for the action, without actually making the request, and provides an error response. If you have the required permissions, the error response is DryRunOperation . Otherwise, it is UnauthorizedOperation .

    :type InstanceIds: list
    :param InstanceIds: One or more instance IDs.
            Default: Describes all your instances.
            Constraints: Maximum 100 explicitly specified instance IDs.
            (string) --

    :type Filters: list
    :param Filters: One or more filters.
            availability-zone - The Availability Zone of the instance.
            event.code - The code for the scheduled event (instance-reboot | system-reboot | system-maintenance | instance-retirement | instance-stop ).
            event.description - A description of the event.
            event.not-after - The latest end time for the scheduled event (for example, 2014-09-15T17:15:20.000Z ).
            event.not-before - The earliest start time for the scheduled event (for example, 2014-09-15T17:15:20.000Z ).
            instance-state-code - The code for the instance state, as a 16-bit unsigned integer. The high byte is an opaque internal value and should be ignored. The low byte is set based on the state represented. The valid values are 0 (pending), 16 (running), 32 (shutting-down), 48 (terminated), 64 (stopping), and 80 (stopped).
            instance-state-name - The state of the instance (pending | running | shutting-down | terminated | stopping | stopped ).
            instance-status.reachability - Filters on instance status where the name is reachability (passed | failed | initializing | insufficient-data ).
            instance-status.status - The status of the instance (ok | impaired | initializing | insufficient-data | not-applicable ).
            system-status.reachability - Filters on system status where the name is reachability (passed | failed | initializing | insufficient-data ).
            system-status.status - The system status of the instance (ok | impaired | initializing | insufficient-data | not-applicable ).
            (dict) --A filter name and value pair that is used to return a more specific list of results. Filters can be used to match a set of resources by various criteria, such as tags, attributes, or IDs.
            Name (string) --The name of the filter. Filter names are case-sensitive.
            Values (list) --One or more filter values. Filter values are case-sensitive.
            (string) --

    :type NextToken: string
    :param NextToken: The token to retrieve the next page of results.

    :type MaxResults: integer
    :param MaxResults: The maximum number of results to return in a single call. To retrieve the remaining results, make another call with the returned NextToken value. This value can be between 5 and 1000. You cannot specify this parameter and the instance IDs parameter in the same call.

    :type IncludeAllInstances: boolean
    :param IncludeAllInstances: When true , includes the health status for all instances. When false , includes the health status for running instances only.
            Default: false

    :rtype: dict
    :return: {
        'InstanceStatuses': [
            {
                'InstanceId': 'string',
                'AvailabilityZone': 'string',
                'Events': [
                    {
                        'Code': 'instance-reboot'|'system-reboot'|'system-maintenance'|'instance-retirement'|'instance-stop',
                        'Description': 'string',
                        'NotBefore': datetime(2015, 1, 1),
                        'NotAfter': datetime(2015, 1, 1)
                    },
                ],
                'InstanceState': {
                    'Code': 123,
                    'Name': 'pending'|'running'|'shutting-down'|'terminated'|'stopping'|'stopped'
                },
                'SystemStatus': {
                    'Status': 'ok'|'impaired'|'insufficient-data'|'not-applicable'|'initializing',
                    'Details': [
                        {
                            'Name': 'reachability',
                            'Status': 'passed'|'failed'|'insufficient-data'|'initializing',
                            'ImpairedSince': datetime(2015, 1, 1)
                        },
                    ]
                },
                'InstanceStatus': {
                    'Status': 'ok'|'impaired'|'insufficient-data'|'not-applicable'|'initializing',
                    'Details': [
                        {
                            'Name': 'reachability',
                            'Status': 'passed'|'failed'|'insufficient-data'|'initializing',
                            'ImpairedSince': datetime(2015, 1, 1)
                        },
                    ]
                }
            },
        ],
        'NextToken': 'string'
    }

    :returns:
    DryRun (boolean) -- Checks whether you have the required permissions for the action, without actually making the request, and provides an error response. If you have the required permissions, the error response is DryRunOperation . Otherwise, it is UnauthorizedOperation .
    InstanceIds (list) -- One or more instance IDs.
    Default: Describes all your instances.
    Constraints: Maximum 100 explicitly specified instance IDs.

    (string) --

    Filters (list) -- One or more filters.

    availability-zone - The Availability Zone of the instance.
    event.code - The code for the scheduled event (instance-reboot | system-reboot | system-maintenance | instance-retirement | instance-stop ).
    event.description - A description of the event.
    event.not-after - The latest end time for the scheduled event (for example, 2014-09-15T17:15:20.000Z ).
    event.not-before - The earliest start time for the scheduled event (for example, 2014-09-15T17:15:20.000Z ).
    instance-state-code - The code for the instance state, as a 16-bit unsigned integer. The high byte is an opaque internal value and should be ignored. The low byte is set based on the state represented. The valid values are 0 (pending), 16 (running), 32 (shutting-down), 48 (terminated), 64 (stopping), and 80 (stopped).
    instance-state-name - The state of the instance (pending | running | shutting-down | terminated | stopping | stopped ).
    instance-status.reachability - Filters on instance status where the name is reachability (passed | failed | initializing | insufficient-data ).
    instance-status.status - The status of the instance (ok | impaired | initializing | insufficient-data | not-applicable ).
    system-status.reachability - Filters on system status where the name is reachability (passed | failed | initializing | insufficient-data ).
    system-status.status - The system status of the instance (ok | impaired | initializing | insufficient-data | not-applicable ).

    (dict) --A filter name and value pair that is used to return a more specific list of results. Filters can be used to match a set of resources by various criteria, such as tags, attributes, or IDs.

    Name (string) --The name of the filter. Filter names are case-sensitive.

    Values (list) --One or more filter values. Filter values are case-sensitive.

    (string) --

    NextToken (string) -- The token to retrieve the next page of results.
    MaxResults (integer) -- The maximum number of results to return in a single call. To retrieve the remaining results, make another call with the returned NextToken value. This value can be between 5 and 1000. You cannot specify this parameter and the instance IDs parameter in the same call.
    IncludeAllInstances (boolean) -- When true , includes the health status for all instances. When false , includes the health status for running instances only.
    Default: false

    """
    pass


def sortDictionaryListByKey(dictList, key, reverse=False):
    """
    _sortDictionaryListByKey_

    Given a list of dictionaries and a key with a numerical
    value, sort that dictionary in order of that key's value.

    NOTE: If the key does not exist, this will not raise an exception
    This is because this is used for sorting of performance histograms
    And not all histograms have the same value
    """
    return sorted(dictList, key=lambda k: k.get(key, 0.0), reverse=reverse)


def _makeNd(array, ndim):
    """
    Pads as many 1s at the beginning of array's shape as are need to give
    array ndim dimensions.
    """
    new_shape = (1,) * (ndim - array.ndim) + array.shape
    return array.reshape(new_shape)


def expect(params, time, unit, period, pr_inf, prev, curr):
    """
    Return the expected observation value :math:`\\mathbb{E}[y_t]` for every
    every particle :math:`x_t`, at one or more times :math:`t`.

    :param params: The observation model parameters.
    :param time: The simulation time(s).
    :param unit: The observation units (see classes in :py:module`data`).
    :type unit: str
    :param period: The duration of the observation period (in days).
    :type period: int
    :param pr_inf: The probability of an individual becoming infected during
        the observation period(s).
    :type pr_inf: float
    :param prev: The state vectors at the start of the observation period(s).
    :type prev: numpy.ndarray
    :param curr: The state vectors at the end of the observation period(s).
    :type curr: numpy.ndarray
    """
    if unit in params['obs']:
        op = params['obs'][unit]
        obs_model = op['obs_model']
        return obs_model.expect(params, op, time, period, pr_inf, prev, curr)
    else:
        raise ValueError("Unknown observation type '{}'".format(unit))


def __new__(cls, *version):
    """
        Create a new tuple.

        :param version: The version tuple
        :type version: any

        :return: A new Version instance
        :rtype: Version
        """
    cls._version = cls._get_version(version)
    return super().__new__(cls, *version)


@staticmethod
def character(index):
    """
        Convert the offset of this character in the current text unit.
        """
    return index


def write_matrix_to_tsv(net, filename=None, df=None):
    """
  This will export the matrix in net.dat or a dataframe (optional df in
  arguments) as a tsv file. Row/column categories will be saved as tuples in
  tsv, which can be read back into the network object.
  """
    import pandas as pd
    if df is None:
        df = net.dat_to_df()
    return df['mat'].to_csv(filename, sep='\t')


def make_ammo(request, case=''):
    """Make phantom ammo file

    Args:
        request (str): HTTP request
        case (str):    ammo mark

    Returns:
        str: string in phantom ammo format
    """
    ammo_template = '%d %s\n%s'
    return ammo_template % (len(request), case, request)


def hidden(func):
    """
    Marks a function as "hidden" - i.e the function can only be resolved on the :class:`.Table` it
    exists on, and **NOT** the :class:`.TableRow` associated with said table.
    """
    func.__hidden__ = True
    return func


def key_assoc_val(d, func, exclude=None):
    """return the key associated with the value returned by func
    """
    vs = list(d.values())
    ks = list(d.keys())
    key = ks[vs.index(func(vs))]
    return key


def add_single_filter(aOutput, iTocIndex, sKeyword, oFilter):
    """Add a single filter's help text to the file"""
    sDesc = oFilter.description
    sLink = sKeyword.lower()
    aOutput.insert(iTocIndex, '## "%s":#%s\n' % (sDesc, sLink))
    iTocIndex += 1
    aOutput.append('h3(#%s). %s\n\n' % (sLink, sDesc))
    try:
        sInput, sRest = oFilter.helptext.split('\n', 1)
        aOutput.append('*Parameters:* %s\n\n' % sInput)
        aOutput.append(sRest)
    except ValueError:
        print('Failed to extract filter details')
        print(oFilter.keyword, oFilter.helptext)
    aOutput.append('\n\n')
    return iTocIndex


def parse_flux_bounds(entry):
    """Return flux bounds for reaction entry.

    Detect flux bounds that are specified using the non-standardized
    kinetic law parameters which are used by many pre-FBC SBML models. The
    flux bounds are returned as a pair of lower, upper bounds. The returned
    bound is None if undefined.

    Args:
        entry: :class:`SBMLReactionEntry`.
    """
    lower_bound = None
    upper_bound = None
    for parameter in entry.kinetic_law_reaction_parameters:
        pid, name, value, units = parameter
        if pid == 'UPPER_BOUND' or name == 'UPPER_BOUND':
            upper_bound = value
        elif pid == 'LOWER_BOUND' or name == 'LOWER_BOUND':
            lower_bound = value
    return lower_bound, upper_bound


def askyn(question, suffix=' (y/n): '):
    """ Asks a yes/no question
    """
    ans = input(question + suffix)
    return ans is 'y' or ans is 'Y'


def set_data(ob, data):
    """Hold data on behalf of an object

        For objects such as storages that
        work with multiple transactions, it's convenient to store
        transaction-specific data on the transaction itself.  The
        transaction knows nothing about the data, but simply holds it
        on behalf of the object.

        The object passed should be the object that needs the data, as
        opposed to simple object like a string. (Internally, the id of
        the object is used as the key.)
        """


def parse_runtime_duration(runtime):
    """Parse duration information from TransXChange runtime code"""
    HOUR_IN_SECONDS = 60 * 60
    MINUTE_IN_SECONDS = 60
    time = 0
    runtime = runtime.split('PT')[1]
    if 'H' in runtime:
        split = runtime.split('H')
        time = time + int(split[0]) * HOUR_IN_SECONDS
        runtime = split[1]
    if 'M' in runtime:
        split = runtime.split('M')
        time = time + int(split[0]) * MINUTE_IN_SECONDS
        runtime = split[1]
    if 'S' in runtime:
        split = runtime.split('S')
        time = time + int(split[0]) * MINUTE_IN_SECONDS
    return time


@classmethod
def fromInstruments(cls, instruments, unk02=0, waveArchiveIDs=None):
    """
        Create a SBNK from a list of instruments.
        """
    obj = cls(unk02=unk02, waveArchiveIDs=waveArchiveIDs)
    obj.instruments = instruments
    return obj


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

        :param FileGetCopyReferenceDetails val:
        :rtype: EventDetails
        """
    return cls('file_get_copy_reference_details', val)


def to_camel_case(field: str, prefix: str) ->str:
    """ Convert a STAR-fusion output column name

    - Remove the prefix (either "Left" or "Right"
    - Convert the first character to lower case
    """
    new_field = field[len(prefix):]
    camel_case = new_field[0].lower() + new_field[1:]
    return camel_case


@classmethod
def modify_url_for_impersonation(cls, url, impersonate_user, username):
    """
        Modify the SQL Alchemy URL object with the user to impersonate if applicable.
        :param url: SQLAlchemy URL object
        :param impersonate_user: Bool indicating if impersonation is enabled
        :param username: Effective username
        """
    pass


def provides_facts():
    """
    Returns a dictionary keyed on the facts provided by this module. The value
    of each key is the doc string describing the fact.
    """
    return {'vc_capable':
        'A boolean indicating if the device is currently configured in a virtual chassis. In spite of the name, this fact does NOT indicate whether or not the device is CAPABLE of joining a VC.'
        , 'vc_mode':
        'A string indicating the current virtual chassis mode of the device.',
        'vc_fabric':
        'A boolean indicating if the device is currently in fabric mode.',
        'vc_master':
        'A string indicating the chassis/node which is currently the master of the VC.'
        }


def divceil(divident, divisor):
    """Integer division with rounding up"""
    quot, r = divmod(divident, divisor)
    return quot + int(bool(r))


def pairwise_squared_distance(x):
    """
    x : (n_samples, n_points, dims)
    return : (n_samples, n_points, n_points)
    """
    x2s = (x * x).sum(-1, keepdim=True)
    return x2s + x2s.transpose(-1, -2) - 2 * x @ x.transpose(-1, -2)


def _getParameter(name, index, args, kwargs, default=None):
    """Find a parameter in tuple and dictionary arguments a function receives"""
    param = kwargs.get(name)
    if len(args) > index:
        if param:
            raise ValueError("Parameter '%s' is specified twice" % name)
        param = args[index]
    return param or default


def psi_K_Na_Cl_PK74(T, P):
    """c-c'-a: potassium sodium chloride [PK74]."""
    psi = -0.0018
    valid = T == 298.15
    return psi, valid


def Pf(lea1):
    """ returns the probability that given lea1 is True;
        the probability is expressed as a float between 0.0 and 1.0;
        raises an exception if the probability type is no convertible to float
        raises an exception if some value in the distribution is not boolean
        (note this is NOT the case with lea1.p(True));
        this is a convenience function equivalent to lea1.Pf
    """
    return lea1.Pf


def normalize_mask(mask, is_micro):
    """    Normalizes the (user specified) mask.

    :param mask: A mask constant
    :type mask: int or None
    :param bool is_micro: Indicates if the mask is meant to be used for a
            Micro QR Code.
    """
    if mask is None:
        return None
    try:
        mask = int(mask)
    except ValueError:
        raise ValueError(
            'Invalid data mask "{0}". Must be an integer or a string which represents an integer value.'
            .format(mask))
    if is_micro:
        if not 0 <= mask < 4:
            raise ValueError(
                'Invalid data mask "{0}" for Micro QR Code. Must be in range 0 .. 3'
                .format(mask))
    elif not 0 <= mask < 8:
        raise ValueError('Invalid data mask "{0}". Must be in range 0 .. 7'
            .format(mask))
    return mask


def PolsAccDeath(t):
    """Number of policies: Accidental death"""
    return 0


def scroll_up(deltax: int=0, deltay: int=0, page: bool=False):
    """Scroll the view up

    :param deltax: Delta X
    :type deltax: int
    :param deltay: Delta Y
    :type deltay: int
    :param page: Page, Scroll up one page
    :type page: bool
    """
    pass


@classmethod
def get_object(cls, api_token, ssh_key_id, mocked):
    """
            Class method that will return a SSHKey object by ID.
        """
    ssh_key = cls(token=api_token, id=ssh_key_id, mocked=mocked)
    ssh_key.mock_data = 'keys/single.json'
    ssh_key.load()
    return ssh_key


def signal(signal_name):
    """
        Issues a signal to Tor. See control-spec or .valid_signals for
        which ones are available and their return values.
        """


def read_in_test_prompt(filename):
    """
    Reads in the prompt from a text file
    Returns string
    """
    prompt_string = open(filename).read()
    return prompt_string


def _sorted_keys_items(dobj):
    """Return dictionary items sorted by key."""
    keys = sorted(dobj.keys())
    for key in keys:
        yield key, dobj[key]


def _is_string_like(obj):
    """
    Check whether obj behaves like a string.
    """
    try:
        obj + ''
    except (TypeError, ValueError):
        return False
    return True


def finger_shading(wf, Sf):
    """Return the fractional power loss due to finger shading (0 to 1)
    where wf is the width of the finger (cm) and Sf is the finger spacing (cm)."""
    return wf / Sf * 100.0


def keys():
    """ Return all cache keys
        """


def calc_rain_kdp_zdr(kdp, zdr, a=90.8, b=0.93, c=-0.169):
    """
    kdp = Specific Differential Phase (deg km^-1)
    zdr = Differential Reflectivity (dB)
    a, b, c = Adjustable function parameters
    """
    return a * kdp ** b * 10.0 ** (c * zdr)


def set_affinity_on_worker():
    """When a new worker process is created, the affinity is set to all CPUs"""


@classmethod
def get_schema(cls):
    """Defines a Schema that the input parameters shall comply to

        :return: A jsonschema format (mandatory default setting)
        :rtype: dict
        """
    return {}


def get_acroversion():
    """ Return version of Adobe Acrobat executable or None"""
    from six.moves import winreg
    adobesoft = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, 'Software\\Adobe')
    for index in range(winreg.QueryInfoKey(adobesoft)[0]):
        key = winreg.EnumKey(adobesoft, index)
        if 'acrobat' in key.lower():
            acrokey = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE,
                'Software\\Adobe\\%s' % key)
            for index in range(winreg.QueryInfoKey(acrokey)[0]):
                numver = winreg.EnumKey(acrokey, index)
                try:
                    res = winreg.QueryValue(winreg.HKEY_LOCAL_MACHINE,
                        'Software\\Adobe\\%s\\%s\\InstallPath' % (key, numver))
                    return res
                except Exception:
                    pass
    return None


def format_datetime(dt):
    """ Format datetime.datetime object to make HAR validator happy """
    return dt.isoformat() + 'Z'


@classmethod
def from_httplib(cls, message):
    """Read headers from a Python 2 httplib message object."""
    headers = []
    for line in message.headers:
        if line.startswith((' ', '\t')):
            key, value = headers[-1]
            headers[-1] = key, value + '\r\n' + line.rstrip()
            continue
        key, value = line.split(':', 1)
        headers.append((key, value.strip()))
    return cls(headers)


def calc_risk_return_ratio(price):
    """
    计算return/risk，基本上等于未经无风险利率调整的夏普率
    """
    return price.mean() / price.std()


def create_article_author_matrix(alist):
    """Creates a matrix articles x authors, marking with 1 the articles
    where the authors participated in.
    Input:  alist - list of articles in a data structure.
    Output: result - articles x authors binary matrix."""
    authors = []
    for a in alist:
        authors += a.authors
    uniq_authors = list(set(authors))
    result = map(lambda a: map(lambda author: author in a.authors,
        uniq_authors), alist)
    return result, uniq_authors


def _process_response(response: object, success: bool) ->str:
    """Process response from batch caller

        Args:
            response (Object): Requests library response object
            success (bool): success condition given by bool or lambda

        Returns:
            str: batch status FINISH | FAILED
        """
    if response.status_code == 200 and response.text:
        batch_data: dict = response.json()
        return batch_data['status']
    if success:
        return 'FINISH'
    return 'FAILED'


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

    This function is not part of the public Enaml api.

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


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

    .. math::
       square(x) = x^2

    Example::

       square([2, 3, 4]) = [4, 9, 16]

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

       - square(default) = default
       - square(row_sparse) = row_sparse
       - square(csr) = csr

    Defined in src/operator/tensor/elemwise_unary_op_pow.cc:L118

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

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

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


@classmethod
def table_name_col(cls):
    """
        Return the name of the metadata column used to store the feature table
        name.
        """
    return 'f_table_name'


def serialize_v1_event(event):
    """Serialize an Event object for the V1 event protocol.

    :param baseplate.events.Event event: An event object.

    """
    return event.serialize()


def det(matrix):
    """Seem sto work fine.

    >> from sympy import *
    >> from sympy.abc import *
    >> Matrix([[a, b], [c, d]]).det()
    a*d - b*c
    >> Matrix([[a, b, c], [d, e, f], [g, h, i]]).det()
    a*e*i - a*f*h - b*d*i + b*f*g + c*d*h - c*e*g

    A few terms can be slightly factored out of the 3x dim.

    >> Matrix([[a, b, c, d], [e, f, g, h], [i, j, k, l], [m, n, o, p]]).det()
    a*f*k*p - a*f*l*o - a*g*j*p + a*g*l*n + a*h*j*o - a*h*k*n - b*e*k*p + b*e*l*o + b*g*i*p - b*g*l*m - b*h*i*o + b*h*k*m + c*e*j*p - c*e*l*n - c*f*i*p + c*f*l*m + c*h*i*n - c*h*j*m - d*e*j*o + d*e*k*n + d*f*i*o - d*f*k*m - d*g*i*n + d*g*j*m

    72 mult vs ~48 in cse'd version'

    Commented out - takes a few seconds
    >> #Matrix([[a, b, c, d, e], [f, g, h, i, j], [k, l, m, n, o], [p, q, r, s, t], [u, v, w, x, y]]).det()

    260 multiplies with cse; 480 without it.
    """
    size = len(matrix)
    if size == 1:
        return matrix[0]
    elif size == 2:
        (a, b), (c, d) = matrix
        return a * d - c * b
    elif size == 3:
        (a, b, c), (d, e, f), (g, h, i) = matrix
        return a * (e * i - h * f) - d * (b * i - h * c) + g * (b * f - e * c)
    elif size == 4:
        (a, b, c, d), (e, f, g, h), (i, j, k, l), (m, n, o, p) = matrix
        return (a * f * k * p - a * f * l * o - a * g * j * p + a * g * l *
            n + a * h * j * o - a * h * k * n - b * e * k * p + b * e * l *
            o + b * g * i * p - b * g * l * m - b * h * i * o + b * h * k *
            m + c * e * j * p - c * e * l * n - c * f * i * p + c * f * l *
            m + c * h * i * n - c * h * j * m - d * e * j * o + d * e * k *
            n + d * f * i * o - d * f * k * m - d * g * i * n + d * g * j * m)
    elif size == 5:
        (a, b, c, d, e), (f, g, h, i, j), (k, l, m, n, o), (p, q, r, s, t), (u,
            v, w, x, y) = matrix
        x0 = s * y
        x1 = a * g * m
        x2 = t * w
        x3 = a * g * n
        x4 = r * x
        x5 = a * g * o
        x6 = t * x
        x7 = a * h * l
        x8 = q * y
        x9 = a * h * n
        x10 = s * v
        x11 = a * h * o
        x12 = r * y
        x13 = a * i * l
        x14 = t * v
        x15 = a * i * m
        x16 = q * w
        x17 = a * i * o
        x18 = s * w
        x19 = a * j * l
        x20 = q * x
        x21 = a * j * m
        x22 = r * v
        x23 = a * j * n
        x24 = b * f * m
        x25 = b * f * n
        x26 = b * f * o
        x27 = b * h * k
        x28 = t * u
        x29 = b * h * n
        x30 = p * x
        x31 = b * h * o
        x32 = b * i * k
        x33 = p * y
        x34 = b * i * m
        x35 = r * u
        x36 = b * i * o
        x37 = b * j * k
        x38 = s * u
        x39 = b * j * m
        x40 = p * w
        x41 = b * j * n
        x42 = c * f * l
        x43 = c * f * n
        x44 = c * f * o
        x45 = c * g * k
        x46 = c * g * n
        x47 = c * g * o
        x48 = c * i * k
        x49 = c * i * l
        x50 = p * v
        x51 = c * i * o
        x52 = c * j * k
        x53 = c * j * l
        x54 = q * u
        x55 = c * j * n
        x56 = d * f * l
        x57 = d * f * m
        x58 = d * f * o
        x59 = d * g * k
        x60 = d * g * m
        x61 = d * g * o
        x62 = d * h * k
        x63 = d * h * l
        x64 = d * h * o
        x65 = d * j * k
        x66 = d * j * l
        x67 = d * j * m
        x68 = e * f * l
        x69 = e * f * m
        x70 = e * f * n
        x71 = e * g * k
        x72 = e * g * m
        x73 = e * g * n
        x74 = e * h * k
        x75 = e * h * l
        x76 = e * h * n
        x77 = e * i * k
        x78 = e * i * l
        x79 = e * i * m
        return (x0 * x1 - x0 * x24 + x0 * x27 + x0 * x42 - x0 * x45 - x0 *
            x7 - x1 * x6 + x10 * x11 - x10 * x21 - x10 * x44 + x10 * x52 +
            x10 * x69 - x10 * x74 - x11 * x20 + x12 * x13 + x12 * x25 - x12 *
            x3 - x12 * x32 - x12 * x56 + x12 * x59 - x13 * x2 + x14 * x15 +
            x14 * x43 - x14 * x48 - x14 * x57 + x14 * x62 - x14 * x9 - x15 *
            x8 + x16 * x17 - x16 * x23 - x16 * x58 + x16 * x65 + x16 * x70 -
            x16 * x77 - x17 * x22 + x18 * x19 + x18 * x26 - x18 * x37 - x18 *
            x5 - x18 * x68 + x18 * x71 - x19 * x4 - x2 * x25 + x2 * x3 + x2 *
            x32 + x2 * x56 - x2 * x59 + x20 * x21 + x20 * x44 - x20 * x52 -
            x20 * x69 + x20 * x74 + x22 * x23 + x22 * x58 - x22 * x65 - x22 *
            x70 + x22 * x77 + x24 * x6 - x26 * x4 - x27 * x6 + x28 * x29 -
            x28 * x34 - x28 * x46 + x28 * x49 + x28 * x60 - x28 * x63 - x29 *
            x33 + x30 * x31 - x30 * x39 - x30 * x47 + x30 * x53 + x30 * x72 -
            x30 * x75 - x31 * x38 + x33 * x34 + x33 * x46 - x33 * x49 - x33 *
            x60 + x33 * x63 + x35 * x36 - x35 * x41 - x35 * x61 + x35 * x66 +
            x35 * x73 - x35 * x78 - x36 * x40 + x37 * x4 + x38 * x39 + x38 *
            x47 - x38 * x53 - x38 * x72 + x38 * x75 + x4 * x5 + x4 * x68 -
            x4 * x71 + x40 * x41 + x40 * x61 - x40 * x66 - x40 * x73 + x40 *
            x78 - x42 * x6 - x43 * x8 + x45 * x6 + x48 * x8 + x50 * x51 -
            x50 * x55 - x50 * x64 + x50 * x67 + x50 * x76 - x50 * x79 - x51 *
            x54 + x54 * x55 + x54 * x64 - x54 * x67 - x54 * x76 + x54 * x79 +
            x57 * x8 + x6 * x7 - x62 * x8 + x8 * x9)
    else:
        import numpy as np
        return float(np.linalg.det(matrix))


@staticmethod
def date_diff(time_point_1=None, time_point_2=None):
    """Return (duration, is_negative) between two TimePoint objects.

        duration -- is a Duration instance.
        is_negative -- is "-" if time_point_2 is in the past of time_point_1.
        """
    if time_point_2 < time_point_1:
        return time_point_1 - time_point_2, '-'
    else:
        return time_point_2 - time_point_1, ''


@staticmethod
def p_a2ml_taggedunion_member_list_optional(p):
    """a2ml_taggedunion_member_list_optional : empty
                                                 | a2ml_taggedunion_member_list"""
    p[0] = tuple() if p[1] is None else p[1]


def force_int(num, default=None):
    """
    Force a value to an integer. If the value
    cannot be converted return the default value.
    """
    try:
        return int(num)
    except (ValueError, TypeError):
        return default


def requires_mfa(profile):
    """Checks to see if the given profile requires MFA.

    Parameters
    ----------
    - profile - the profile to inspect

    Returns
    -------
    True if the profile requires MFA, False if it doesn't.
    """
    return 'mfa_serial' in profile


@staticmethod
def __checksum_to_etag(checksum):
    """将crc/md5转为etag，当前默认转为str类型"""
    return str(checksum)


def ndarray_to_list(o):
    """Convert a Numpy ndarray into a list of values

    Args:
        o (numpy.ndarray): Data to convert

    Returns:
        list: Python list of data
    """
    return o.tolist()


def lchop(text, beginning):
    """ Removes the beginning from the text if the text starts with it. """
    if text.startswith(beginning):
        return text[len(beginning):]
    return text


@classmethod
def for_input(cls, value, validate=True):
    """
        Convert the fixed width into a CSS class.

        Args:
            value: the width.
            validate: check whether the width is a fixed value.

        Raises:
            ValueError: if validate is True and the value is invalid.

        Returns:
            str: the CSS class used to set the width of a Text input.

        """
    if validate and not cls.is_valid(value):
        raise ValueError('Unexpected fixed width', value)
    return 'govuk-input--width-%d' % value


@classmethod
def get_configuration_for_impersonation(cls, uri, impersonate_user, username):
    """
        Return a configuration dictionary that can be merged with other configs
        that can set the correct properties for impersonating users
        :param uri: URI string
        :param impersonate_user: Bool indicating if impersonation is enabled
        :param username: Effective username
        :return: Dictionary with configs required for impersonation
        """
    return {}


@classmethod
def shadow(cls, address):
    """Shadow an existing libzmq context

        address is the integer address of the libzmq context
        or an FFI pointer to it.

        .. versionadded:: 14.1
        """
    from zmq.utils.interop import cast_int_addr
    address = cast_int_addr(address)
    return cls(shadow=address)


def _print_to_element(multiline_element, *args, end=None, sep=None,
    text_color=None, background_color=None, autoscroll=True):
    """
    Print like Python normally prints except route the output to a multline element and also add colors if desired

    :param multiline_element:  The multiline element to be output to
    :type multiline_element: (Multiline)
    :param args:  The arguments to print
    :type args: List[Any]
    :param end:  The end char to use just like print uses
    :type end: (str)
    :param sep:  The separation character like print uses
    :type sep: (str)
    :param text_color: color of the text
    :type text_color: (str)
    :param background_color: The background color of the line
    :type background_color: (str)
    :param autoscroll: If True (the default), the element will scroll to bottom after updating
    :type autoscroll: Bool
    """
    end_str = str(end) if end is not None else '\n'
    sep_str = str(sep) if sep is not None else ' '
    outstring = ''
    num_args = len(args)
    for i, arg in enumerate(args):
        outstring += str(arg)
        if i != num_args - 1:
            outstring += sep_str
    outstring += end_str
    multiline_element.update(outstring, append=True, text_color_for_value=
        text_color, background_color_for_value=background_color, autoscroll
        =autoscroll)


def is_member_mutable(context, member):
    """Return True if the image is mutable in this context."""
    if context.is_admin:
        return True
    if context.owner is None:
        return False
    return member.member_id == context.owner


def formula_2014_01_01(foyer_fiscal, period, parameters):
    """
        Investissements outre-mer dans le logement social (déclaration n°2042 IOM)
        2014
        """
    fhkg = foyer_fiscal('fhkg', period)
    fhkh = foyer_fiscal('fhkh', period)
    fhki = foyer_fiscal('fhki', period)
    fhqj = foyer_fiscal('fhqj', period)
    fhqk = foyer_fiscal('fhqk', period)
    fhqn = foyer_fiscal('fhqn', period)
    fhqs = foyer_fiscal('fhqs', period)
    fhqu = foyer_fiscal('fhqu', period)
    fhqw = foyer_fiscal('fhqw', period)
    fhqx = foyer_fiscal('fhqx', period)
    fhra = foyer_fiscal('fhra', period)
    fhrb = foyer_fiscal('fhrb', period)
    fhrc = foyer_fiscal('fhrc', period)
    fhrd = foyer_fiscal('fhrd', period)
    fhxa = foyer_fiscal('fhxa', period)
    fhxb = foyer_fiscal('fhxb', period)
    fhxc = foyer_fiscal('fhxc', period)
    fhxe = foyer_fiscal('fhxe', period)
    report_reduc_2009 = fhkg
    report_reduc_2010 = fhkh + fhki
    report_reduc_2011 = fhqn + fhqu + fhqk
    report_reduc_2012 = fhqj + fhqs + fhqw + fhqx
    report_reduc_2013 = fhra + fhrb + fhrc + fhrd
    reduc_invest_2014 = fhxa + fhxb + fhxc + fhxe
    return (report_reduc_2009 + report_reduc_2010 + report_reduc_2011 +
        report_reduc_2012 + report_reduc_2013 + reduc_invest_2014)


@staticmethod
def _match_hits(hit_list):
    """Using a hit list, determine a path-to-fileid map.

        The hit list is a list of (count, path, file_id), where count is a
        (possibly float) number, with higher numbers indicating stronger
        matches.
        """
    seen_file_ids = set()
    path_map = {}
    for count, path, file_id in sorted(hit_list, reverse=True):
        if path in path_map or file_id in seen_file_ids:
            continue
        path_map[path] = file_id
        seen_file_ids.add(file_id)
    return path_map


def n_params(model):
    """Return the number of parameters in a pytorch model.

    Args:
        model (nn.Module): The model to analyze.

    Returns:
        int: The number of parameters in the model.
    """
    pp = 0
    for p in list(model.parameters()):
        nn = 1
        for s in list(p.size()):
            nn = nn * s
        pp += nn
    return pp


@classmethod
def filter_app_factory(cls, app, global_conf, prefix='', **app_conf):
    """URL paths are whitespace delimited"""
    obj = cls(app)
    optname = prefix + cls.URL_MATCH_LIST_OPTNAME
    obj.urlpath_match_list = app_conf[optname].split()
    return obj


def iterable_p(coll):
    """
    Confirms if a collection is iterable
    @sig iterable_p :: [a] -> bool
    """
    return hasattr(coll, '__len__')


def _clean_lc(lc):
    """ Perform Lightkurve operations on object.

    Performes basic cleaning of a light curve, removing nans, outliers,
    median filtering etc.

    Parameters
    ----------
    lc : Lightkurve.LightCurve instance
        Lightkurve object to be cleaned

    Returns
    -------
    lc : Lightkurve.LightCurve instance
        The cleaned Lightkurve object

    """
    lc = lc.remove_nans().normalize().flatten().remove_outliers()
    return lc


def is_pcap(pcap):
    """
    Simple test for pcap magic bytes in supplied file.

    :param pcap: File path to Pcap file to check
    :returns: True if content is pcap (magic bytes present), otherwise False.
    """
    with open(pcap, 'rb') as tmp:
        header = tmp.read(4)
        if header == b'\xa1\xb2\xc3\xd4' or header == b'\xd4\xc3\xb2\xa1':
            return True
        return False


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


@staticmethod
def in_var(file):
    """Name of variable used to read in contents of file."""
    return f'{file.name_without_ext}_in'


def p_overset(p):
    """math_object : OVERSET argument argument """
    p[3].above = p[2]
    p[0] = [p[3]]


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

        :param str val:
        :rtype: GroupSelector
        """
    return cls('group_external_id', val)


def orange(text):
    """ Return this text formatted orange (olive) """
    return '\x0307%s\x03' % text


@staticmethod
def _mutate_label(label: str) ->str:
    """
        Redshift only supports lowercase column names and aliases.

        :param label: Expected expression label
        :return: Conditionally mutated label
        """
    return label.lower()


def lower_string(input_string):
    """
    Convert string to lower TestCase

    argparse type function

    Args
        input_string: Input string to converts

    Returns:
        lower case of input string
    """
    return input_string.lower()


def cym():
    """The complements of the primaries"""
    return 'cyan yellow magenta'.split()


def listenUDP(port, protocol, interface='', maxPacketSize=8192):
    """
        Connects a given L{DatagramProtocol} to the given numeric UDP port.

        @param port: A port number on which to listen.
        @type port: C{int}

        @param protocol: A L{DatagramProtocol} instance which will be
            connected to the given C{port}.
        @type protocol: L{DatagramProtocol}

        @param interface: The local IPv4 or IPv6 address to which to bind;
            defaults to '', ie all IPv4 addresses.
        @type interface: C{str}

        @param maxPacketSize: The maximum packet size to accept.
        @type maxPacketSize: C{int}

        @return: object which provides L{IListeningPort}.
        """


def table_cells_to_regions(table):
    """
    Transform from a table of Cell objects to a table of cell region coordinates.
    This is primarily for testing purposes.

    """
    _table = []
    for row in table.rows:
        _row = []
        for cell in row:
            _row.append(cell.region)
        _table.append(_row)
    return _table


def xfb(data):
    """emulates xfb command from topspin"""
    return data.bk_xf2().bk_xf1()


def calculate_vehicle_mass(unladen_mass, passengers_mass, cargo_mass):
    """
    Calculate vehicle_mass [kg].

    :param unladen_mass:
        Unladen mass [kg].
    :type unladen_mass: float

    :param passengers_mass:
        Passengers mass including the driver [kg].
    :type passengers_mass: float

    :param cargo_mass:
        Cargo mass [kg].
    :type cargo_mass: float

    :return:
        Vehicle mass [kg].
    :rtype: float
    """
    return unladen_mass + passengers_mass + cargo_mass


def check_none(value_to_check):
    """
    Helper function that checks for None values from the GitHub APIs.
    """
    return value_to_check if value_to_check is not None else 'None'


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

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

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