def create_pop_count_op(names, op_code, shifts, BW_in, BW_out, module_name,
    reset_name, depth):
    """
    Creates an popcount tree op
    names = [ out_name, a_name, b_name, c_name ]
    op_code = 0 -> - a - b - c
    op_code = 1 -> - a - b + c
    op_code = 2 -> - a + b - c
    op_code = 3 -> - a + b + c
    op_code = 4 ->   a - b - c
    op_code = 5 ->   a - b + c
    op_code = 6 ->   a + b - c
    op_code = 7 ->   a + b + c
    shifts = [ shift_a, shift_b, shift_c ]
    BW_in -> the bitwidth of the input
    BW_out -> the bitwidth of the output
    module_name -> the name to call the adder
    reset_name -> the reset to use, will assert the reset on the cycle before use ( not used in this op )
    depth -> how deep the op is down the tree, inputs have a depth of 0 ( not used in this op )
    """
    assert names[3] == str(BW_out
        ) + "'h0", 'Three inputs not implemented in this adder'
    assert shifts[0] == 0 and shifts[1
        ] == 0, 'Shift registers not implemented in this adder'
    bw = depth + BW_in + 3
    if bw > BW_out:
        bw = BW_out
    op_str = ''
    if depth == 0:
        op_str = ' $signed( '
    op_mod = 4
    for n in names[1:3]:
        if op_code < op_mod:
            op_str += ' - '
        elif op_mod != 4:
            op_str += ' + '
        op_code = op_code % op_mod
        op_mod = op_mod >> 1
        if depth == 0:
            op_str += " { %d'b0, %s } " % (bw - BW_in, n)
        else:
            op_str += '$signed( %s ) ' % n
    if depth == 0:
        op_str += ' )'
    add_op = (
        'reg [%d:0] %s;\nalways @( posedge clock ) begin\n%s <= %s;\nend\n' %
        (bw - 1, names[0], names[0], op_str))
    return add_op, bw


def allowedRolesAndUsers():
    """ Return a sequence roles and users with View permission.

        o PortalCatalog indexes this sequence to allow filtering out items
          a user is not allowed to see.
        """


@classmethod
def DeregisterFormatter(cls, formatter_class):
    """Deregisters a formatter class.

    The formatter classes are identified based on their lower case data type.

    Args:
      formatter_class (type): class of the formatter.

    Raises:
      KeyError: if formatter class is not set for the corresponding data type.
    """
    formatter_data_type = formatter_class.DATA_TYPE.lower()
    if formatter_data_type not in cls._formatter_classes:
        raise KeyError('Formatter class not set for data type: {0:s}.'.
            format(formatter_class.DATA_TYPE))
    del cls._formatter_classes[formatter_data_type]
    if formatter_data_type in cls._formatter_objects:
        del cls._formatter_objects[formatter_data_type]


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 factorial_get_prime_pow(n, p):
    """
    Return power of prime @p in @n!
    """
    count = 0
    ppow = p
    while ppow <= n:
        count += n // ppow
        ppow *= p
    return count


def unicode_to_environ(s, enc='UTF-8'):
    """
    Return a unicode string encoded for a WSGI environ value

    In python 2 this function returns ``s`` encoded using the specified
    encoding

    In python 3 this returns a 'bytes-as-unicode' string:

    - encode ``s`` using the specified encoding (eg utf8)
    - decode the resulting byte string as latin-1
    """
    return s.encode(enc, 'surrogateescape').decode('iso-8859-1')


def from_unicode_coding(unicode_stream):
    """
    Convert the Unicode stream back into Packets.

    """
    raise NotImplementedError()


def label(x):
    """
    Return the label

    """
    return x.label


def getRAMCacheKey(request, etag=None, lastModified=None):
    """Calculate the cache key for pages cached in RAM.

    ``etag`` is a unique etag string.

    ``lastModified`` is a datetime object giving the last=modified
     date for the resource.

    The cache key is a combination of the resource's URL, the etag,
    and the last-modified date. Both the etag and last=modified are
    optional but in most cases that are worth caching in RAM, the etag
    is needed to ensure the key changes when the resource view changes.
    """
    resourceKey = '{0}{1}?{2}'.format(request.get('SERVER_URL', ''),
        request.get('PATH_INFO', ''), request.get('QUERY_STRING', ''))
    if etag:
        resourceKey = '|' + etag + '||' + resourceKey
    if lastModified:
        resourceKey = '|' + str(lastModified) + '||' + resourceKey
    return resourceKey


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

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

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

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

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

    """
    pass


def retrieve_tape_recovery_point(TapeARN=None, GatewayARN=None):
    """
    Retrieves the recovery point for the specified virtual tape. This operation is only supported in the tape gateway architecture.
    A recovery point is a point in time view of a virtual tape at which all the data on the tape is consistent. If your gateway crashes, virtual tapes that have recovery points can be recovered to a new gateway.
    See also: AWS API Documentation

    Examples
    Retrieves the recovery point for the specified virtual tape.
    Expected Output:

    :example: response = client.retrieve_tape_recovery_point(
        TapeARN='string',
        GatewayARN='string'
    )

    :type TapeARN: string
    :param TapeARN: [REQUIRED]
            The Amazon Resource Name (ARN) of the virtual tape for which you want to retrieve the recovery point.

    :type GatewayARN: string
    :param GatewayARN: [REQUIRED]
            The Amazon Resource Name (ARN) of the gateway. Use the ListGateways operation to return a list of gateways for your account and region.

    :rtype: dict
    :return: {
        'TapeARN': 'string'
    }

    """
    pass


def sortHKLd(HKLd, ifreverse, ifdup, ifSS=False):
    """sort reflection list on d-spacing; can sort in either order

    :param HKLd: a list of [h,k,l,d,...];
    :param ifreverse: True for largest d first
    :param ifdup: True if duplicate d-spacings allowed
    :return: sorted reflection list
    """
    T = []
    N = 3
    if ifSS:
        N = 4
    for i, H in enumerate(HKLd):
        if ifdup:
            T.append((H[N], i))
        else:
            T.append(H[N])
    D = dict(zip(T, HKLd))
    T.sort()
    if ifreverse:
        T.reverse()
    X = []
    okey = ''
    for key in T:
        if key != okey:
            X.append(D[key])
        okey = key
    return X


def common_start(first_number, last_number):
    """ Get the common starting characters of the two strings first_number and last_number """
    str_first = str(first_number)
    str_last = str(last_number)
    common = ''
    for a, b in zip(list(str_first), list(str_last)):
        if a == b:
            common = common + a
        else:
            return common
    return None


@staticmethod
def getFBCTVariables():
    """ FBCT variables in cals.
        """
    FBCTvariables = ['LHC.BCTFR.A6R4.B1:BUNCH_INTENSITY',
        'LHC.BCTFR.A6R4.B2:BUNCH_INTENSITY']
    return FBCTvariables


def add_logging_options_to_parser(parser):
    """Add logging options to the parser.

    :param argparse.ArgumentParser parser: The parser to add the args to

    """
    group = parser.add_argument_group(title='Logging Options')
    group.add_argument('-L', '--log-file', action='store', help=
        'Log to the specified filename. If not specified, log output is sent to STDOUT'
        )
    group.add_argument('-v', '--verbose', action='store_true', help=
        'Increase output verbosity')
    group.add_argument('--debug', action='store_true', help=
        'Extra verbose debug logging')


def bw():
    """The simplest of all - no colour and full colour"""
    return 'black white'.split()


@classmethod
def parse_list(cls, api, json_list):
    """
            Parse a list of JSON objects into
            a result set of model instances.
        """
    results = []
    for json_obj in json_list:
        if json_obj:
            obj = cls.parse(api, json_obj)
            results.append(obj)
    return results


def parse_size(size_input: str) ->int:
    """Takes a size string from the config and turns it into int(bytes)."""
    prefixes = [None, 'K', 'M', 'G', 'T', 'P']
    try:
        return int(size_input)
    except ValueError:
        size_input = size_input.upper().rstrip('IB')
        value, unit = float(size_input[:-1]), size_input[-1:]
        if unit not in prefixes:
            raise ValueError(
                "should be in format '0-x (KiB, MiB, GiB, TiB, PiB)'")
        return int(1024 ** prefixes.index(unit) * value)


def qbytearray_to_str(qba):
    """Convert QByteArray object to str in a way compatible with Python 2/3"""
    return str(bytes(qba.toHex().data()).decode())


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,


def _get_counts(number=None, default=None):
    """Split a number into a list of divisors and the remainder.
    The divisor is the default count in this case."""
    if not number:
        number = 1
    div = divmod(number, default)
    result = [default for x in range(div[0])]
    if div[1] != 0:
        return result + [div[1]]
    return result


@staticmethod
def parse(args):
    """
        Split arguments.
        """
    args = args.split()
    if len(args) != 2:
        return args
    try:
        args[1] = 8 - int(args[1])
        if not 0 <= args[1] < 8:
            print('out of range row')
            raise ValueError
    except ValueError:
        print('not int', args[1])
        return ()
    try:
        args[0] = ord(args[0]) - ord('a')
        if not 0 <= args[1] < 8:
            print('out of range column')
            raise ValueError
    except ValueError:
        print('not char', args[0])
        return ()
    return args


def clip(value, minimum=-float('inf'), maximum=float('inf')):
    """Signal hard clipping"""
    if value < minimum:
        return minimum
    if value > maximum:
        return maximum
    return value


@classmethod
def parse(cls, parser, text, pos):
    """Checks if terminal token is a keyword after lower-casing it."""
    match = cls.regex.match(text)
    if match:
        if match.group(0).lower() not in cls.grammar:
            result = text, SyntaxError(repr(match.group(0)) +
                ' is not a member of ' + repr(cls.grammar))
        else:
            result = text[len(match.group(0)):], cls(match.group(0))
    else:
        result = text, SyntaxError('expecting ' + repr(cls.__name__))
    return result


def json_patch(from_obj, to_obj, ignore_keys=None, only_keys=None,
    no_remove=False):
    """
    Creates a JSON patch diff between two objects.

    Arguments:
    from_obj (dict): from object, usually the existing object returned by API
    to_obj (dict): to object, usually the new object to return

    Keyword arguments:
    ignore_keys (list of str, optional): whether to ignore any keys (e.g. not patch them)
    only_keys (list of str, optional): only patch keys from this whitelist
    no_remove (bool, optional): don't remove any keys when patching (in case you forgot
                                to specify certain keys in the object)
    """
    ops = []
    for key in to_obj:
        if ignore_keys is not None and key in ignore_keys:
            continue
        if only_keys is not None and key not in only_keys:
            continue
        if key not in from_obj or from_obj[key] is None:
            ops.append({'op': 'add', 'path': '/%s' % key, 'value': to_obj[key]}
                )
        elif from_obj[key] != to_obj[key]:
            ops.append({'op': 'replace', 'path': '/%s' % key, 'value':
                to_obj[key]})
    if no_remove is False:
        for key in from_obj:
            if ignore_keys is not None and key in ignore_keys:
                continue
            if only_keys is not None and key not in only_keys:
                continue
            if key not in to_obj or to_obj[key] is None:
                ops.append({'op': 'remove', 'path': '/%s' % key})
    return ops


def diff_response_time_dicts(latest, old):
    """
    Returns the delta between two {response_times:request_count} dicts.

    Used together with the response_times cache to get the response times for the
    last X seconds, which in turn is used to calculate the current response time
    percentiles.
    """
    new = {}
    for time in latest:
        diff = latest[time] - old.get(time, 0)
        if diff:
            new[time] = diff
    return new


def __call__():
    """Renders template to a response object."""


def impl_ret_new_ref(ctx, builder, retty, ret):
    """
    The implementation returns a new reference.
    """
    return ret


def shared_representations(objects):
    """Returns representations that are shared by all `objects`"""
    objects = list(objects.values())
    reps = set(objects[0].representations())
    for obj in objects[1:]:
        reps &= set(obj.representations())
    return reps


def product(target, prop1, prop2, **kwargs):
    """
    Calculates the product of multiple property values

    Parameters
    ----------
    target : OpenPNM Object
        The object which this model is associated with. This controls the
        length of the calculated array, and also provides access to other
        necessary properties.

    prop1 : string
        The name of the first argument

    prop2 : string
        The name of the second argument

    Returns
    -------
    value : NumPy ndarray
        Array containing product values of ``target[prop1]``, ``target[prop2]``

    Notes
    -----
    Additional properties can be specified beyond just ``prop1`` and ``prop2``
    by including additional arguments in the function call (i.e. ``prop3 =
    'pore.foo'``).

    """
    value = target[prop1] * target[prop2]
    for item in kwargs.values():
        value *= target[item]
    return value


@classmethod
def __is_bool__(cls, name: str) ->bool:
    """Tell if the type of the prop defined by `name` is ``bool``.

        Parameters
        ----------
        name : str
            The name of the prop we ask for.

        Returns
        -------
        bool
            ``True`` if the type of the prop is ``bool``. False otherwise.

        """
    return cls.__type__(name) is bool


def remove_keys(_dict, keys):
    """Remove keys from a dictionary."""
    if not _dict:
        return {}
    new = dict(_dict)
    for key in keys:
        new.pop(key, None)
    return new


def forward_random_state(random_state):
    """
    Forward the internal state of a random state.

    This makes sure that future calls to the random_state will produce new random values.

    Parameters
    ----------
    random_state : numpy.random.RandomState
        Random state to forward.

    """
    random_state.uniform()


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 write(value: str, *args):
    """Intended to be used when value is multiline."""
    print(value, *args)


@staticmethod
def choose_ub(objective):
    """
        Choose uncertain_bits according to the dimension size automatically.

        :param objective: an Objective object
        :return: uncertain bits
        """
    dim = objective.get_dim()
    dim_size = dim.get_size()
    is_discrete = dim.is_discrete()
    if is_discrete is False:
        if dim_size <= 100:
            ub = 1
        elif dim_size <= 1000:
            ub = 2
        else:
            ub = 3
    elif dim_size <= 10:
        ub = 1
    elif dim_size <= 50:
        ub = 2
    elif dim_size <= 100:
        ub = 3
    elif dim_size <= 1000:
        ub = 4
    else:
        ub = 5
    return ub


def is_iterable(iterable):
    """ Check if input is iterable

    :param iterable:
    :return:
    """
    try:
        iter(iterable)
        return True
    except TypeError:
        return False


def is_naive(dt):
    """Determines if a given datetime.datetime is naive."""
    return dt.tzinfo is None or dt.tzinfo.utcoffset(dt) is None


def call_user_func(settings_module, func_name, *args, **kwargs):
    """Call a user-supplied settings function and clean it up afterwards.

    settings_module may be None, or the function may not exist.
    If the function exists, it is called with the specified *args and **kwargs,
    and the result is returned.
    """
    if settings_module:
        if hasattr(settings_module, func_name):
            func = getattr(settings_module, func_name)
            try:
                return func(*args, **kwargs)
            finally:
                delattr(settings_module, func_name)


def max_subarray(A):
    """
    Maximum subarray problem
    """
    max_ending_here = max_so_far = A[0]
    for x in A[1:]:
        max_ending_here = max(x, max_ending_here + x)
        max_so_far = max(max_so_far, max_ending_here)
    return max_so_far


def reprocess_urls(urls, patterns, dbclient=None):
    """
    Reprocess the cached URLs which matches the pattern(s)
    """
    if not urls:
        urls = []
    if isinstance(patterns, str):
        patterns = [patterns]
    cur = dbclient.cursor()
    wheres = ['url~%s'] * len(patterns)
    query = 'SELECT url FROM urls WHERE {}'.format(' OR '.join(wheres))
    cur.execute(query, patterns)
    for row in cur.fetchall():
        urls.append(row[0])
    return urls


def first(func, iter):
    """Find the first item in an iterable for which func(item) is True.
    If not item is find None is returned."""
    for i in iter:
        if func(i):
            return i
    else:
        return None


def psi_H_Na_OH_HMW84(T, P):
    """c-c'-a: hydrogen sodium hydroxide [HMW84]."""
    psi = 0
    valid = T == 298.15
    return psi, valid


def chunks(l, n):
    """Yield successive n-sized chunks from l."""
    for i in range(0, len(l), n):
        yield l[i:i + n]


def put_data(f, data, big=True, isfloat=False):
    """
    Put data to file object with given endianness and data type.
    """
    if isfloat:
        if big:
            f.write(data.astype('>f8').tostring())
        else:
            f.write(data.astype('<f8').tostring())
    elif big:
        f.write(data.astype('>i4').tostring())
    else:
        f.write(data.astype('<i4').tostring())
    return


def calcDownscaleFactor(P_REQ, p_max_values, downsc_coeffs, dsc_v_split,
    p_rated, v_max, f_downscale_threshold):
    """Check if downscaling required, and apply it.

    :return: (float) the factor

    @see: Annex 1-7, p 68
    """
    p_req_max = P_REQ[p_max_values[0]]
    r_max = p_req_max / p_rated
    if dsc_v_split is not None:
        assert len(downsc_coeffs) == 2, downsc_coeffs
        downsc_coeffs = downsc_coeffs[0
            ] if v_max <= dsc_v_split else downsc_coeffs[1]
    if downsc_coeffs is None:
        f_downscale = 0
    else:
        r0, a1, b1 = downsc_coeffs
        if r_max < r0:
            f_downscale = 0
        else:
            f_downscale = a1 * r_max + b1
            f_downscale = round(f_downscale, 1)
            if f_downscale <= f_downscale_threshold:
                f_downscale = 0
    return f_downscale


def MULTIPLY(*expressions):
    """
    Multiplies numbers together and returns the result.
    See https://docs.mongodb.com/manual/reference/operator/aggregation/multiply/
    for more details
    :param expressions: An array of numbers or fields
    :return: Aggregation operator
    """
    return {'$multiply': list(expressions)}


@staticmethod
def nested_set(dict, keys, value, key_delimiter='.'):
    """ Set the value of a nested dictionary at the nested key sequence `keys`

        Args:
            dict (:obj:`dict`): dictionary to retrieve value from
            keys (:obj:`str` or :obj:`list`): list of nested keys to retrieve
            value (:obj:`object`): desired value of `dict` at key sequence `keys`
            key_delimiter (:obj:`str`, optional): delimiter for `keys`

        Returns:
            :obj:`object`: Modified input dictionary
        """
    if isinstance(keys, str):
        keys = keys.split(key_delimiter)
    last_key = keys.pop()
    nested_dict = dict
    for key in keys:
        if key not in nested_dict:
            nested_dict[key] = {}
        nested_dict = nested_dict[key]
    nested_dict[last_key] = value
    return dict


@classmethod
def from_public_key(cls, public_key):
    """Constructs an Address object from a public key"""
    return cls(None, public_key, None, 'normal')


def KK_RC6_fit(params, w, t_values):
    """
    Kramers-Kronig Function: -RC-

    Kristian B. Knudsen (kknu@berkeley.edu / kristianbknudsen@gmail.com)
    """
    Rs = params['Rs']
    R1 = params['R1']
    R2 = params['R2']
    R3 = params['R3']
    R4 = params['R4']
    R5 = params['R5']
    R6 = params['R6']
    return Rs + R1 / (1 + w * 1.0j * t_values[0]) + R2 / (1 + w * 1.0j *
        t_values[1]) + R3 / (1 + w * 1.0j * t_values[2]) + R4 / (1 + w *
        1.0j * t_values[3]) + R5 / (1 + w * 1.0j * t_values[4]) + R6 / (1 +
        w * 1.0j * t_values[5])


def string_is_hex(color_str):
    """
    Returns whether or not given string is a valid hexadecimal string
    :param color_str: str
    :return: bool
    """
    if color_str.startswith('#'):
        return len(color_str) in (4, 7, 9)
    else:
        return len(color_str) in (3, 6, 8)


def parse_uri(uri):
    """Parses a EIP681 Payment URI into this class"""


def get_total_checks(output_list):
    """Get total checks."""
    return sum(1 for output in output_list if 'status' in output)


def copy():
    """Copy selected text to clipboard

    """
    pass


def _get_size(hyper):
    """ return the number of choices from 'something',
    something can be either an hyper-parameter but also a constant or a tuple

    This allow implicite use of list/tuple to model a choice and object to model a constant

    """
    if hasattr(hyper, 'size'):
        return hyper.size
    elif isinstance(hyper, (list, tuple)):
        return len(hyper)
    elif hasattr(hyper, 'rvs'):
        return 10
    else:
        return 1


@classmethod
def keys(cls, fqdn, sort_by=None):
    """Display keys information about a domain."""
    meta = cls.get_fqdn_info(fqdn)
    url = meta['domain_keys_href']
    return cls.json_get(cls.get_sort_url(url, sort_by))


def parse_free_results(stdout):
    """Parse results of `free` command

  Parameters
  ----------
  stdout : str
    Output of running `free` command

  Returns
  -------
  int
    Free Disk space
  """
    line = stdout.split('\n')[1]
    assert 'Mem:' in line
    return int(line.split()[3])


def p_case_clause(p):
    """case_clause : pattern_list
                   | case_clause_sequence pattern_list"""
    raise NotImplementedError('case clause')


@classmethod
def configurable_default(cls):
    """Returns the implementation class to be used if none is configured."""
    raise NotImplementedError()


@classmethod
def register(cls, scheme, challenge_class):
    """Registers a class to represent a challenge in scheme

        scheme
            A string representing an auth scheme, e.g., 'Basic'.  The
            string is converted to lower-case before it is registered
            to allow for case insensitive look-up.

        challenge_class
            A class derived from Challenge that is used to represent a
            Challenge issued using that scheme

        If a class has already been registered for the scheme it is
        replaced.  The mapping is kept in the :attr:`scheme_class`
        dictionary."""
    cls.scheme_class[scheme.lower()] = challenge_class


@classmethod
def addToArchive(cls, archive_pathname, added_pathname, in_archive_name=
    None, is_folder=False):
    """ Create archive if not existing
        """
    if archive_pathname.endswith(cls.archive_ext):
        with cls.opening_function(archive_pathname, 'a') as handle:
            if not is_folder:
                handle.write(added_pathname, arcname=in_archive_name)
            else:
                cls._add_folder_function(handle, added_pathname)
            try:
                cls.get_element(handle, in_archive_name)
            except KeyError:
                errmsg = ' '.join(['added element', added_pathname,
                    'With archive name', in_archive_name,
                    'abscent in archive', archive_pathname])
                return errmsg
    else:
        errmsg = ' '.join(['Invalid', cls.archive_ext, 'file:',
            archive_pathname])
    return None


@staticmethod
def to_nullable_array(value):
    """
        Converts value into array object.
        Single values are converted into arrays with a single element.

        :param value: the value to convert.

        :return: array object or None when value is None.
        """
    if value == None:
        return None
    if type(value) == list:
        return value
    if type(value) in [tuple, set]:
        return list(value)
    return [value]


@classmethod
def partial(cls):
    """Inform that this class load complete data"""
    return False


def tilt_clear():
    """Clear the tilt of selected control points

    """
    pass


def change_motions_comments(apps, schema_editor):
    """
    Index the comments fields in the config. Changing from an array to a dict with the
    ids as keys. CHange all motions from an array for comments to a dict with the comments
    field id as key to link motion comments and comments fields.
    """
    ConfigStore = apps.get_model('core', 'ConfigStore')
    Motion = apps.get_model('motions', 'Motion')
    try:
        config_comments_fields = ConfigStore.objects.get(key='motions_comments'
            ).value
    except ConfigStore.DoesNotExist:
        config_comments_fields = []
    comments_fields = {}
    for index, field in enumerate(config_comments_fields):
        comments_fields[index + 1] = field
    max_index = len(config_comments_fields) - 1
    try:
        db_value = ConfigStore.objects.get(key='motions_comments')
    except ConfigStore.DoesNotExist:
        db_value = ConfigStore(key='motions_comments')
    db_value.value = comments_fields
    db_value.save()
    for motion in Motion.objects.all():
        comments = {}
        for index, comment in enumerate(motion.comments or []):
            if index > max_index:
                break
            comments[index + 1] = comment
        motion.comments = comments
        motion.save(skip_autoupdate=True)


def key_for_name(name):
    """Return the key name used to store the given queue name in Redis."""
    return 'hotqueue:%s' % name


def isWifiSSIDAvailable(ssid, chuteStor, name):
    """Make sure this SSID is available."""
    chList = chuteStor.getChuteList()
    for ch in chList:
        if name != ch.name:
            otherSSIDs = ch.getChuteSSIDs()
            for o in otherSSIDs:
                if o == ssid:
                    return False
    return True


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


@staticmethod
def _prob_distance(extent: int, standard_distance: float) ->float:
    """
        Calculates the probabilistic distance of an observation.
        :param extent: the extent value specified during initialization.
        :param standard_distance: the standard distance of the input
        observation.
        :return: the probabilistic distance.
        """
    return extent * standard_distance


@classmethod
def parse_fromfile(cls, nmap_report_path, data_type='XML', incomplete=False):
    """
            Call generic cls.parse() method and ensure that a correct file             path is given as argument. If not, an exception is raised.

            :param nmap_data: Same as for parse().             Any portion of nmap scan reports could be passed as argument.             Data type _must be a valid path to a file containing             nmap scan results.

            :param data_type: Specifies the type of serialization in the file.

            :param incomplete: enable you to parse interrupted nmap scans             and/or incomplete nmap xml blocks by adding a </nmaprun> at             the end of the scan.
            :type incomplete: boolean

            :return: NmapObject
        """
    try:
        with open(nmap_report_path, 'r') as fileobj:
            fdata = fileobj.read()
            rval = cls.parse(fdata, data_type, incomplete)
    except IOError:
        raise
    return rval


def escape_html(text):
    """Replace <, >, &, " with their HTML encoded representation. Intended to
    prevent HTML errors in rendered displaCy markup.

    text (unicode): The original text.
    RETURNS (unicode): Equivalent text to be safely used within HTML.
    """
    text = text.replace('&', '&')
    text = text.replace('<', '<')
    text = text.replace('>', '>')
    text = text.replace('"', '"')
    return text


def manage_addUser(REQUEST, kwargs):
    """ Create a new user record. If REQUEST is not None, it will be
        used to retrieve the values for the user record.

        To use this method from Python you must pass None as the REQUEST
        argument and a dictionary called *kwargs* containing key/value pairs
        for the user record attributes.

        The dictionary of values passed in, be it REQUEST or kwargs, must at
        the very least contain the following keys and values:

        o *cn* or *uid* (depending on what you set the RDN attribute to)

        o *user_pw* (the new user record's password)

        o *confirm_pw* (This must match password)

        o all attributes your user record LDAP schema must contain (consult
          your LDAP server schema)

        Only those attributes and values are used that are specified on the
        LDAP Schema tab of your LDAPUserFolder.

        Permission: *Manage users*
        """


def homogeneous_to_cartesian(homogeneous_matrix):
    """Convert an homogeneous matrix to cartesian matrix"""
    return homogeneous_matrix[:-1, :-1]


def unescape(s):
    """Replace escaped HTML-special characters by their originals."""
    if '&' not in s:
        return s
    s = s.replace('<', '<')
    s = s.replace('>', '>')
    s = s.replace(''', "'")
    s = s.replace('"', '"')
    s = s.replace('&', '&')
    return s


def get_or_create_h2o():
    """
    Gets or initiates and H2O session
    :return:
    """
    import h2o
    h2o.init()
    return h2o


@staticmethod
def process_unix(path, family, inodes, filter_pid=None):
    """Parse /proc/net/unix files.

        :param path: path of the file to process
        :param family: one of socket.AF_INET, socket.AF_INET6, socket.AF_UNIX
        :param inodes: the dictionary output from ``self.get_*_inodes()``
        :param filter_pid: Optional. Only return sockets owned by this process
        """
    file = open(path, 'r')
    file.readline()
    for line in file:
        tokens = line.split()
        _, _, _, _, type_, _, inode = tokens[0:7]
        if inode in inodes:
            pairs = inodes[inode]
        else:
            pairs = [(None, -1)]
        for pid, fd in pairs:
            if filter_pid is not None and filter_pid != pid:
                continue
            else:
                if len(tokens) == 8:
                    path = tokens[-1]
                else:
                    path = ''
                type_ = int(type_)
                raddr = None
                status = 'NONE'
                yield fd, family, type_, path, raddr, status, pid
    file.close()


def addDataladDatasetUUID(project_uuid, bidsroot_directory, graph):
    """
    This function will add the datalad unique ID for this dataset to the project entity uuid in graph. This
    UUID will ultimately be used by datalad to identify the dataset
    :param project_uuid: unique project activity ID in graph to add tuple
    :param bidsroot_directory: root directory for which to collect datalad uuids
    :return: augmented graph with datalad unique IDs
    """


def rms_contrast(image):
    """
    Calculates the RMS contrast - basically the standard deviation of the image

    Parameters:
        image (ndarray): Image array

    Returns:
        float: Contrast value
    """
    image /= image.max()
    return float(image.std())


@staticmethod
def get_frq_shift_nums(n, fs, shift_frq):
    """
        根据采样率和移频量，计算数据需要的移频点数，计算公式(不为整数时取四舍五入):
        return = shift_frq*n/fs
        :param n: fft变换的长度，也既数据长度
        :param fs:
        :param shift_frq:
        :return: 采样点右移数
        """
    return round(shift_frq * n / fs)


def toFieldValue(value):
    """Convert an input value to a field/system internal value.

        This methods *must* also validate the converted value against the
        field.

        If the conversion fails, a ``ValueError`` *must* be raised. If
        the validation fails, a ``ValidationError`` *must* be raised.
        """


def construct_authorperm(*args):
    """ Create a post identifier from comment/post object or arguments.
    Examples:

        .. code-block:: python

            >>> from crea.utils import construct_authorperm
            >>> print(construct_authorperm('username', 'permlink'))
            @username/permlink
            >>> print(construct_authorperm({'author': 'username', 'permlink': 'permlink'}))
            @username/permlink

    """
    username_prefix = '@'
    if len(args) == 1:
        op = args[0]
        author, permlink = op['author'], op['permlink']
    elif len(args) == 2:
        author, permlink = args
    else:
        raise ValueError('construct_identifier() received unparsable arguments'
            )
    fields = dict(prefix=username_prefix, author=author, permlink=permlink)
    return '{prefix}{author}/{permlink}'.format(**fields)


def add_peers(peerids=set):
    """
        Update my internal state to include the peers in peerids as
        potential candidates for storing a file.
        """


def extractCredentials(request):
    """Looks for an email address in __ac_name,
           finds the first user with that email and ex-changes the email with the username in the request.

           Always returns {} to simulate failed extraction this will trigger continued PAS extraction of credentials.
        """


@staticmethod
def _is_name(tokens):
    """
        Returns True if provided tokens constitutes a complete name.

        A complete name has at least two name tokens or at least a name token
        and an initial token.
        """
    name_count = 0
    initial_count = 0
    for token in tokens:
        if token.type == 'NAME':
            name_count += 1
        elif token.type == 'INITIAL':
            initial_count += 1
    if name_count >= 2 or name_count == 1 and initial_count >= 1:
        return True
    return False


def st_join_enumerate(items, sep='SEP', comma=','):
    """
    joins strings using an sequential seperator

    example:
      st_join_enumerate(["a","b","c"])
      'a,SEP1,b,SEP2,c'
    """
    ret = ''
    for a, b in enumerate(items):
        if a == 0:
            ret = b
        else:
            ret += comma + sep + str(a) + comma + b
    return ret


def call_task(current_task, object_json):
    """
    run current tuak with arguments
    :param current_task:
    :param object_json: Json
    :return:
    """
    position_args = object_json.arguments['positional']
    keyword_args = object_json.arguments['keyword']
    current_task(*position_args, **keyword_args)


def min(input, dim):
    """Reduce min the input tensor along the given dim.

    Parameters
    ----------
    input : Tensor
        The input tensor.
    dim : int
        The reduce dim.

    Returns
    -------
    Tensor
        A framework-specific tensor.
    """
    pass


def p_field_id(p):
    """field_id : INTCONSTANT ':' """
    p[0] = p[1]


def remove_ruleset(rulesengine_db, name):
    """removes a ruleset from the list of rulesets"""
    from src.praxxis.sqlite import connection
    conn = connection.create_connection(rulesengine_db)
    cur = conn.cursor()
    remove_ruleset = 'DELETE FROM "RulesEngine" WHERE Name = ?'
    cur.execute(remove_ruleset, (name,))
    conn.commit()
    conn.close()


def get_doc_for_type_scheme(type_scheme: 'Type') ->str:
    """ Return a class documentation string for the given type scheme. Use the default_yaml method. """
    return ("""

    .. code-block:: yaml

        {default_yaml}

    """.
        format(default_yaml='\n        '.join(type_scheme.
        string_representation().split('\n'))))


def context_scale_float(data_path: str='', value: float=1.0):
    """Scale a float context value

    :param data_path: Context Attributes, RNA context string
    :type data_path: str
    :param value: Value, Assign value
    :type value: float
    """
    pass


def ensure_unique_obs_ids_in_wide_data(obs_id_col, wide_data):
    """
    Ensures that there is one observation per row in wide_data. Raises a
    helpful ValueError if otherwise.

    Parameters
    ----------
    obs_id_col : str.
        Denotes the column in `wide_data` that contains the observation ID
        values for each row.
    wide_data : pandas dataframe.
        Contains one row for each observation. Should contain the specified
        `obs_id_col` column.

    Returns
    -------
    None.
    """
    if len(wide_data[obs_id_col].unique()) != wide_data.shape[0]:
        msg = 'The values in wide_data[obs_id_col] are not unique, '
        msg_2 = 'but they need to be.'
        raise ValueError(msg + msg_2)
    return None


def constant(interval=1):
    """Generator for constant intervals.

    Args:
        interval: The constant value in seconds to yield.
    """
    while True:
        yield interval


def memory():
    """Determine memory specifications of the machine.

    Returns
    -------
    mem_info : dictonary
        Holds the current values for the total, free and used memory of the system.
    """
    mem_info = {}
    with open('/proc/meminfo') as file:
        c = 0
        for line in file:
            lst = line.split()
            if str(lst[0]) == 'MemTotal:':
                mem_info['total'] = int(lst[1])
            elif str(lst[0]) in ('MemFree:', 'Buffers:', 'Cached:'):
                c += int(lst[1])
        mem_info['free'] = c
        mem_info['used'] = mem_info['total'] - c
    return mem_info


@classmethod
def reset_ids(cls):
    """
        Reset the ID counter.  This should not be needed in normal use.
        """
    cls.__count = 0


@staticmethod
def p_value_description_list(p):
    """value_description_list : value_description
                                  | value_description value_description_list"""
    try:
        p[0] = [p[1]] + p[2]
    except IndexError:
        p[0] = [p[1]]


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

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


def is_hex(s):
    """Return whether s is a hex string."""
    try:
        int(s, 16)
    except (TypeError, ValueError):
        return False
    return True


def _spray_stringified_data(connection, data, record_set, logical_file,
    overwrite, delete_workunit):
    """
    Spray stringified data to a HPCC logical file. To generate the
    stringified data and recordset, see `stringify_rows()` &
    `make_record_set()`

    Parameters
    ----------
    connection: `Connection`
        HPCC Connection instance, see also `Connection`.
    data: str
        Stringified data generated by `stringify_rows()`.
    record_set: str
        Recordset generated by `make_record_set()`.
    logical_file: str
        Logical file name on THOR.
    overwrite: bool
        Should the file overwrite any pre-existing logical file.
    delete_workunit: bool
        Delete the workunit once completed

    Returns
    -------
    None
    """
    script_content = (
        "a := DATASET([{}], {{{}}});\nOUTPUT(a, ,'{}' , EXPIRE(1)".format(
        data, record_set, logical_file))
    if overwrite:
        script_content += ', OVERWRITE'
    script_content += ');'
    connection.run_ecl_string(script_content, True, delete_workunit, stored
        =None)


def work_format(work):
    """Return a numerical interpretation of a categorical variable.

    Take in a string representing a categorical variable representing
    an amplitude of a phenomenon as "High", "Medium" and any other word,
    e.g. "Low", and return an integer representing the amplitude: 2, 1, 0
    respectively.

    Parameters
    ----------
    work : str
        String representing a categorical variable.

    Returns
    -------
    int
        Integer value of the work rate: 0, 1 or 2.

    Notes
    -----
    This function is used on the FIFA19 data set to convert the description
    of player's work rate ("High", "Medium" and "Low") into an integer in
    order to enable some of the Machine Learning algorithms to make use of
    the properties.

    Examples
    --------
    >>> w = work_format("High")
    >>> print(w)
    2

    >>> w = work_format("Low")
    >>> print(w)
    0

    >>> w = work_format("Poor")
    >>> print(w)
    0
    """
    if work == 'High':
        return 2
    elif work == 'Medium':
        return 1
    else:
        return 0


def __call__(*args, **kwargs):
    """
        Create and return the object.
        """


@classmethod
def create(cls, **kwargs) ->object:
    """Create a new object using kwargs as attributes

        This method can be override during inheritence,
        ensure to call :meth:`._create` to create the actual object.

        You MUST call :meth:`.commit` to actually commit object
        to database.
        """
    return cls._create(**kwargs)


def str_fsize(sz):
    """
    Formats file size as string (i.e., 1.2 Mb)
    """
    if sz < 1024:
        return '%.1f bytes' % sz
    sz /= 1024.0
    if sz < 1024:
        return '%.1f KB' % sz
    sz /= 1024.0
    if sz < 1024:
        return '%.1f MB' % sz
    sz /= 1024.0
    if sz < 1024:
        return '%.1f GB' % sz
    sz /= 1024.0
    return '%.1f TB' % sz


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

        :param SharingFileAccessError val:
        :rtype: RemoveFileMemberError
        """
    return cls('access_error', val)


def normalize_email(email):
    """Lowercase ``email`` and remove its leading and trailing whitespace.

    >>> normalize_email('A@A.COM')
    'a@a.com'
    >>> normalize_email('	  a@a.com
')
    'a@a.com'

    """
    return email.strip().lower()


def scale(input, H0=0, H=1):
    """ Scale input to range [H0, H] """
    return H0 + input * (H - H0)


def df2a(dataframe):
    """Convert single column dataframe to pure np.ndarray type."""
    data_n_1 = dataframe.dropna().values
    data_n = data_n_1.reshape((len(data_n_1),))
    return data_n


def generate_snapshot_metadata(context, image_api, image_id, instance):
    """Generate a metadata dictionary for an instance snapshot.

    :param context: Nova security context.
    :param image_api: Handle to the glance image API.
    :param image_id: UUID of the prepared glance image.
    :param instance: The Nova instance whose disk is to be snapshotted.
    :return: A dict of metadata suitable for image_api.update.
    """
    image = image_api.get(context, image_id)
    metadata = {'name': image['name'], 'status': 'active', 'disk_format':
        'raw', 'container_format': 'bare', 'properties': {'image_location':
        'snapshot', 'image_state': 'available', 'owner_id': instance.
        project_id}}
    return metadata


def render():
    """Render the plain widget without additional layout"""


def h2x(h):
    """ Horizontal world coords `h` --> document x-coordinates.

        This stub will be replaced by __init__.
        """
    raise Exception(
        'Internal error: h2x was not initialized properly. Please contact the administrator ,-)'
        )


def _create_dictionary(sequences):
    """
    Create id/token mappings for sequences.
    :param sequences: list of token sequences
    :return: mappings from id to token, and token to id
    """
    tokens = {}
    for s in sequences:
        for token in s:
            tokens[token] = tokens.get(token, 0) + 1
    sorted_tokens = sorted(tokens.items(), key=lambda x: -x[1])
    id2token = []
    token2id = {}
    for i, (t, _) in enumerate(sorted_tokens):
        id2token.append(t)
        token2id[t] = i
    return id2token, token2id


@staticmethod
def has_battery():
    """Return whether the device has a battery."""
    return False


def count_unique_peaks(peaks):
    """Returns the number of unique peaks."""
    n_unique = 0
    for chrom in peaks.chroms:
        for peak in peaks.fetch(chrom):
            if not peak.iscommon:
                n_unique += 1
    return n_unique


def delete_user_policy(UserName=None, PolicyName=None):
    """
    Deletes the specified inline policy that is embedded in the specified IAM user.
    A user can also have managed policies attached to it. To detach a managed policy from a user, use  DetachUserPolicy . For more information about policies, refer to Managed Policies and Inline Policies in the IAM User Guide .
    See also: AWS API Documentation

    Examples
    The following delete-user-policy command removes the specified policy from the IAM user named Juan:
    Expected Output:

    :example: response = client.delete_user_policy(
        UserName='string',
        PolicyName='string'
    )

    :type UserName: string
    :param UserName: [REQUIRED]
            The name (friendly name, not ARN) identifying the user that the policy is embedded in.
            This parameter allows (per its regex pattern ) a string of characters consisting of upper and lowercase alphanumeric characters with no spaces. You can also include any of the following characters: =,.@-

    :type PolicyName: string
    :param PolicyName: [REQUIRED]
            The name identifying the policy document to delete.
            This parameter allows (per its regex pattern ) a string of characters consisting of upper and lowercase alphanumeric characters with no spaces. You can also include any of the following characters: =,.@-

    :return: response = client.delete_user_policy(
        PolicyName='ExamplePolicy',
        UserName='Juan',
    )

    print(response)

    """
    pass


def epsilon_Tee_Gotoh_Steward_2(Tc, omega):
    """Calculates Lennard-Jones depth of potential-energy minimum.
    Uses critical temperature and acentric factor. CSP method by [1]_.

    .. math::
        \\epsilon/k = (0.7915 + 0.1693 \\omega)T_c

    Parameters
    ----------
    Tc : float
        Critical temperature of fluid [K]
    omega : float
        Acentric factor for fluid, [-]

    Returns
    -------
    epsilon_k : float
        Lennard-Jones depth of potential-energy minimum over k, [K]

    Notes
    -----
    Further regressions with other parameters were performed in [1]_ but are
    not included here, except for `epsilon_Tee_Gotoh_Steward_1`.

    Examples
    --------
    >>> epsilon_Tee_Gotoh_Steward_2(560.1, 0.245)
    466.55125785

    References
    ----------
    .. [1] Tee, L. S., Sukehiro Gotoh, and W. E. Stewart. "Molecular Parameters
       for Normal Fluids. Lennard-Jones 12-6 Potential." Industrial &
       Engineering Chemistry Fundamentals 5, no. 3 (August 1, 1966): 356-63.
       doi:10.1021/i160019a011
    """
    epsilon_k = (0.7915 + 0.1693 * omega) * Tc
    return epsilon_k


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 unpack_numpy(var, count, dtype, buff):
    """
    create numpy deserialization code
    """
    return var + ' = numpy.frombuffer(%s, dtype=%s, count=%s)' % (buff,
        dtype, count)


def is_symplectic(form):
    """
    Checks whether or not a given form is symplectic.

    :param form: A form.
    :return: Boolean representing if a form is symplectic or not.
    """
    if form is None:
        return False
    if len(form.shape) != 2:
        return False
    if form.shape[0] % 2 != 0 or form.shape[0] != form.shape[1]:
        return False
    out = True
    for ii in range(form.shape[0]):
        for jj in range(form.shape[1]):
            if ii == jj:
                if form[ii, jj] != 0:
                    out = False
            if ii != jj:
                if form[ii, jj] != -form[jj, ii]:
                    out = False
    return out


def _format_123(num):
    """The simplest formatter"""
    return str(num)


def when_done():
    """Return a Deferred that fires when the operation is complete. It
        will fire with the operation status, the same value as returned by
        get_status()."""


def get_doi_csl_item_zotero(doi):
    """
    Generate CSL JSON Data for a DOI using Zotero's translation-server.
    """
    from manubot.cite.zotero import get_csl_item
    return get_csl_item(f'doi:{doi}')


@classmethod
def info(cls):
    """
        @param: empty intended
        return list of possbile join combinations
        """
    raise NotImplementedError(
        '> Datafram.jointer info(): method is not implemented. ')


def sanitize(name):
    """
    Sanitize the specified ``name`` for use with breathe directives.

    **Parameters**

    ``name`` (:class:`python:str`)
        The name to be sanitized.

    **Return**

    :class:`python:str`
        The input ``name`` sanitized to use with breathe directives (primarily for use
        with ``.. doxygenfunction::``).  Replacements such as ``"<" -> "<"`` are
        performed, as well as removing spaces ``"< " -> "<"`` must be done.  Breathe is
        particularly sensitive with respect to whitespace.
    """
    return name.replace('<', '<').replace('>', '>').replace('&', '&'
        ).replace('< ', '<').replace(' >', '>').replace(' &', '&').replace('& '
        , '&')


def calc_relative_density_boulanger_et_al_2014_cpt_values(q_c1n, c_dq=0.9):
    """
    Table 4.1 in PM4Sand v3.1 manual

    Parameters
    ----------
    q_c1n: array_like
        Normalised cone penetration resistance
    c_dq: float, default=0.9 (from :cite:`Idriss:2008ua`)
        Correlation factor, (range 0.64-155 from Salgado (1997)

    Returns
    -------
    array_like
    """
    return 0.465 * (q_c1n / c_dq) ** 0.264 - 1.063


def doBoundingBoxesIntersect(a, b, c, d):
    """
    Check if bounding boxes do intersect. If one bounding box touches
    the other, they do intersect.
    First segment is of points a and b, second of c and d.
    """
    ll1_x = min(a[0], b[0])
    ll2_x = min(c[0], d[0])
    ll1_y = min(a[1], b[1])
    ll2_y = min(c[1], d[1])
    ur1_x = max(a[0], b[0])
    ur2_x = max(c[0], d[0])
    ur1_y = max(a[1], b[1])
    ur2_y = max(c[1], d[1])
    return (ll1_x <= ur2_x and ur1_x >= ll2_x and ll1_y <= ur2_y and ur1_y >=
        ll2_y)


def date_to_str(dt, with_timezone=False):
    """
    Convert datetime to str

    Parameters
    ----------
    dt : datetime
        datetime to convert
    with_timezone : bool, default False
        Include timezone or not

    Returns
    -------
    datetime_str : str
        Datetime string
    """
    if with_timezone and dt.tzinfo:
        dtstr = dt.strftime('%Y-%m-%dT%H:%M:%S.%f%z')
        return dtstr[:-2] + ':' + dtstr[-2:]
    else:
        return dt.strftime('%Y-%m-%dT%H:%M:%S.%f')


def _layer_size_score(size, hole_count, hole_area):
    """ Heuristic used for determining the correct file number interpretation.
    Lower is better.
    """
    board_area = size[0] * size[1]
    if board_area == 0:
        return 0
    hole_percentage = hole_area / board_area
    hole_score = (hole_percentage - 0.25) ** 2
    size_score = (board_area - 8) ** 2
    return hole_score * size_score


def merge_cookies(resp):
    """ Merge the cookies that were set on this response with the given
        resp object (which can be any WSGI application).  If the resp is a
        webob.Response object, then the other object will be modified
        in-place. """


def convert2boolean(arg):
    """convert2boolean is used for environmental variables that must be
    returned as boolean"""
    if not isinstance(arg, bool):
        return arg.lower() in ('yes', 'true', 't', '1', 'y')
    return arg


def _call_power_from_driver(k, mu, theta):
    """
    Update the model and call power(k,mu) from the global driver
    instance

    This is defined at the module level so we can pickle it
    """
    from pyRSD.rsdfit import GlobalFittingDriver
    driver = GlobalFittingDriver.get()
    driver.theory.set_free_parameters(theta)
    return driver.model.power(k, mu)


def bytes(bits=None, kilobytes=None, megabytes=None, gigabytes=None,
    terabytes=None, petabytes=None):
    """Usage: Convert to bytes. Example: bytes(gigabytes=2)"""
    if bits is not None:
        return bits / 8
    elif kilobytes is not None:
        return kilobytes * 1000
    elif megabytes is not None:
        return megabytes * 1000000.0
    elif gigabytes is not None:
        return gigabytes * 1000000000.0
    elif terabytes is not None:
        return terabytes * 1000000000000.0
    elif petabytes is not None:
        return petabytes * 1000000000000000.0
    else:
        raise Exception(
            'You must specify one value. Example: bits, kilobytes, megabytes, gigabytes, terabytes, petabytes'
            )


def assign_url(context):
    """Create a new URL for the context and assign it to the context."""


def scan_deployed_policies(org_client):
    """
    Return list of Service Control Policies deployed in Organization
    """
    return org_client.list_policies(Filter='SERVICE_CONTROL_POLICY')['Policies'
        ]


def tokenize_line(line):
    """
    Tokenize a line:
    * split tokens on whitespace
    * treat quoted strings as a single token
    * drop comments
    * handle escaped spaces and comment delimiters
    """
    ret = []
    escape = False
    quote = False
    tokbuf = ''
    ll = list(line)
    while len(ll) > 0:
        c = ll.pop(0)
        if c.isspace():
            if not quote and not escape:
                if len(tokbuf) > 0:
                    ret.append(tokbuf)
                tokbuf = ''
            elif quote:
                tokbuf += c
            elif escape:
                tokbuf += c
                escape = False
            else:
                tokbuf = ''
            continue
        if c == '\\':
            escape = True
            continue
        elif c == '"':
            if not escape:
                if quote:
                    ret.append(tokbuf)
                    tokbuf = ''
                    quote = False
                    continue
                else:
                    quote = True
                    continue
        elif c == ';':
            if not escape:
                ret.append(tokbuf)
                tokbuf = ''
                break
        tokbuf += c
        escape = False
    if len(tokbuf.strip(' ').strip('\n')) > 0:
        ret.append(tokbuf)
    return ret


def prepare(doc):
    """
    Prepare the document

    Arguments
    ---------
        doc:
            The pandoc document
    """
    doc.defined = []
    meta = doc.get_metadata('pandoc-beamer-block')
    if isinstance(meta, list):
        for definition in meta:
            if isinstance(definition, dict
                ) and 'classes' in definition and isinstance(definition[
                'classes'], list):
                definition['classes'] = frozenset(definition['classes'])
                definition['type'] = definition.get('type', 'info')
                doc.defined.append(definition)


def Xchunked(X, blocksize):
    """Utility function that chunks up a large design matrix

    Note that this may not always be the ideal way to go, as "real" iterators
    might also allow loading chunks of data from external sources, such as data
    bases.

    Args:
        X: full design matrix
        blocksize: number of rows for each matrix chunk

    Yields:
        blocksize rows from the full matrix X
    """
    i = -blocksize
    while i < X.shape[0] - blocksize:
        i += blocksize
        yield X[i:i + blocksize]


def find_outliers_Z(data, col=None):
    """Use scipy to calcualte absoliute Z-scores
    and return boolean series where True indicates it is an outlier

    Args:
        data (DataFrame,Series,or ndarray): data to test for outliers.
        col (str): If passing a DataFrame, must specify column to use.

    Returns:
        [boolean Series]: A True/False for each row use to slice outliers.

    EXAMPLE USE:
    >> idx_outs = find_outliers_df(df,col='AdjustedCompensation')
    >> good_data = data[~idx_outs].copy()
    """
    import pandas as pd
    from scipy import stats
    import numpy as np
    if isinstance(data, pd.DataFrame):
        if col is None:
            raise Exception('If passing a DataFrame, must provide col=')
        else:
            data = data[col]
    elif isinstance(data, np.ndarray):
        data = pd.Series(data)
    elif isinstance(data, pd.Series):
        pass
    else:
        raise Exception('data must be a DataFrame, Series, or np.ndarray')
    z = np.abs(stats.zscore(data))
    idx_outliers = np.where(z > 3, True, False)
    return idx_outliers


@classmethod
def format_pair(cls, pair):
    """format the pair argument to format understood by remote API."""
    if isinstance(pair, list):
        return pair
    pair = pair.replace('-', cls.delimiter)
    if not pair.isupper():
        return pair.upper()
    else:
        return pair


def merge_logs(bet_logs, bet_results_logs):
    """Merges bet logs (LogBet) with bet results logs (LogResult)."""
    merged_logs = ()
    bet_results_dict = {}
    for bet_result in bet_results_logs:
        bet_id = bet_result['bet_id']
        bet_results_dict = dict(bet_results_dict, **{bet_id: bet_result})
    for bet_log in bet_logs:
        bet_id = bet_log['bet_id']
        bet_result = bet_results_dict.get(bet_id)
        merged_log = {'bet_log': bet_log, 'bet_result': bet_result}
        merged_logs += merged_log,
    return merged_logs


def dump_wintab():
    """Dump WinTab info."""
    try:
        from pyglet.input import wintab
    except:
        print('WinTab not available.')
        return
    interface_name = wintab.get_interface_name()
    impl_version = wintab.get_implementation_version()
    spec_version = wintab.get_spec_version()
    print('WinTab: %s %d.%d (Spec %d.%d)' % (interface_name, impl_version >>
        8, impl_version & 255, spec_version >> 8, spec_version & 255))


def ss(paths):
    """Download subtitles for multiple video files via periscope."""
    from ss import main
    from subsystem.subsystem import devnull
    with devnull():
        main(['ss'] + paths)


def write_file(filename, content, mode='w'):
    """write_file will open a file, "filename" and write content, "content"
        and properly close the file
    """
    with open(filename, mode) as filey:
        filey.writelines(content)
    return filename


def _normalize_dataframe(dataframe, index):
    """Take a pandas DataFrame and count the element present in the
    given columns, return a hierarchical index on those columns
    """
    data = dataframe[index].dropna()
    grouped = data.groupby(index, sort=False)
    counted = grouped[index].count()
    averaged = counted.mean(axis=1)
    return averaged


def join(zelf, *args, **kwargs):
    """ join threads started while handling this event. """
    for thr in zelf._thrs:
        thr.join(*args, **kwargs)


def gravityCorrection(fahrenheit: float, specificGravity: float,
    calibrationFahrenheit: float) ->float:
    """
    Determines Gravity Temperature Correction.

    Parameters
    ----------
    fahrenheit : float
        Temperature in fahrenheit.
    specificGravity : float
        Specific gravity.
    calibrationFahrenheit : float
        Calibration temperature in fahrenheit

    Returns
    -------
    float
        Gravity temperature correction.
    """
    return specificGravity * ((1.00130346 - 0.000134722124 * fahrenheit +
        2.04052596e-06 * pow(fahrenheit, 2) - 2.32820948e-09 * pow(
        fahrenheit, 3)) / (1.00130346 - 0.000134722124 *
        calibrationFahrenheit + 2.04052596e-06 * pow(calibrationFahrenheit,
        2) - 2.32820948e-09 * pow(calibrationFahrenheit, 3)))


@classmethod
def from_domain(cls, domain, array=None, parameters=None, log_level=30):
    """Create Nansat object from input Domain [and array with data]

        Parameters
        ----------
        domain : Domain
            Defines spatial reference system and geographical extent.
        array : numpy NDarray
            Data for the first band. Shape must correspond to shape of <domain>
        parameters : dict
            Metadata for the first band. May contain 'name', 'wkv' and other keys.
        log_level : int
            Level of logging.

        """
    n = cls.__new__(cls)
    n._init_from_domain(domain, array, parameters, log_level)
    return n


def ensure_list(x, except_false=True):
    """
    若传入的对象不为列表，则转化为列表

    :param x: 输入对象
    :param except_false: None, False 等例外，会直接返回原值
    :return: 列表，或 None, False 等
    :rtype: list
    """
    if isinstance(x, (list, tuple)) or not x and except_false:
        return x
    return [x]


def mirror_mag_h(height_image, height_object):
    """Usage: Find magnification using height of image and height of object"""
    return height_image / height_object


def _check_pair(minterm1, minterm2):
    """
    Checks if a pair of minterms differs by only one bit. If yes, returns
    index, else returns -1.

    """
    index = -1
    for x, (i, j) in enumerate(zip(minterm1, minterm2)):
        if i != j:
            if index == -1:
                index = x
            else:
                return -1
    return index


def take_away(y):
    """take_away(y)(x) = x - y

    Be careful with this because subtraction is not commutative.
    The flipped version of this is 'take_away_from'

    >>> list(map(take_away(2), [1,2,3,4,5]))
    [-1, 0, 1, 2, 3]
    """
    return lambda x: x - y


def karel_air_from_saturation(Sr, qfit=0.5):
    """Relative air peremability (w.r.t. dry_ka)

    krel = (1-Sr)**0.5*(1-Sr**(1 / qfit))**(2*qfit)

    Parameters
    ----------
    Sr : 1d array of float
        Degree of saturation at which to calc relative permeability of air.
    qfit : float, optional
        Fitting parameter.  Generally between between 0 and 1.
        Default qfit=1

    References
    ----------
    .. [1] Ba-Te, B., Limin Zhang, and Delwyn G. Fredlund. "A General
           Air-Phase Permeability Function for Airflow through Unsaturated
           Soils." In Proceedings of Geofrontiers 2005 Cngress,
           2961-85. Austin, Tx: ASCE, 2005. doi:10.1061/40787(166)29.

    """
    return (1 - Sr) ** 0.5 * (1 - Sr ** (1 / qfit)) ** (2 * qfit)


def iter_lines(filename):
    """ Iterate over screen names in a file, one per line."""
    with open(filename, 'rt') as idfile:
        for line in idfile:
            screen_name = line.strip()
            if len(screen_name) > 0:
                yield screen_name.split()[0]


def update_my_user_profile(SshPublicKey=None):
    """
    Updates a user's SSH public key.
    See also: AWS API Documentation

    :example: response = client.update_my_user_profile(
        SshPublicKey='string'
    )

    :type SshPublicKey: string
    :param SshPublicKey: The user's SSH public key.

    """
    pass


@classmethod
def _import(cls) ->None:
    """ Attempts to import the dependency so a meaningful ImportError is shown. """
    import torch


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 delete_data_source(DataSourceId=None):
    """
    Assigns the DELETED status to a DataSource , rendering it unusable.
    After using the DeleteDataSource operation, you can use the  GetDataSource operation to verify that the status of the DataSource changed to DELETED.
    Caution: The results of the DeleteDataSource operation are irreversible.
    See also: AWS API Documentation

    :example: response = client.delete_data_source(
        DataSourceId='string'
    )

    :type DataSourceId: string
    :param DataSourceId: [REQUIRED]
            A user-supplied ID that uniquely identifies the DataSource .

    :rtype: dict
    :return: {
        'DataSourceId': 'string'
    }

    """
    pass


def get_xml_value(elem, sub_elem):
    """ xml helper function """
    return elem.getElementsByTagName(sub_elem)[0].firstChild.data


@staticmethod
def get_elastic_mappings(es_major):
    """Get Elasticsearch mapping.

        :param es_major: major version of Elasticsearch, as string
        :returns:        dictionary with a key, 'items', with the mapping
        """
    mapping = """
        {
            "properties": {
                "text_analyzed": {
                  "type": "text",
                  "fielddata": true,
                  "index": true
                }
           }
        } """
    return {'items': mapping}


def maximum(key):
    """
	Curried version of the built-in max.

	>>> Stream([3, 5, 28, 42, 7]) >> maximum(lambda x: x%28)
	42
	"""
    return lambda s: max(s, key=key)


def orphans_purge(num_deleted=0):
    """Clear all orphaned data-blocks without any users from the file

    """
    pass


def memory_usage_mb(df, *args, **kwargs):
    """Dataframe memory usage in MB. """
    return df.memory_usage(*args, **kwargs).sum() / 1024 ** 2


def bytes_to_str(b: bytes) ->str:
    """Attempts to convert a null-terminated bytes object of any length to a string"""
    content = b.split(b'\x00', 1)[0]
    return content.decode('ASCII')


@staticmethod
def delta_days(date1, date2):
    """
        return days of (date2 - date1)
        """
    if type(date1).__name__ == 'LunarDate':
        date1 = date1.to_datetime()
    if type(date2).__name__ == 'LunarDate':
        date2 = date2.to_datetime()
    return date2 - date1


def extract_proper_nouns(sent_toks, container):
    """
		NNP: Proper Noun Singular
		NNPS: Proper Noun plural
		CC: Coordinating conjunction
		IN: Preposition or subordinating conjunction

		The goal here is to extract multi-word proper nouns. E.g.,
			"Hurricane harvey" (NNP NNP)
			"Centers for Disease Control" (NNP IN NNP NNP)
			"Federal Emergency Management Agency" (NNP NNP NNP NNP)
		This is achieved extracting a contiguous list of NNP or a contiguous list of NNP interleaved with CC or IN
	"""
    if len(sent_toks) == 0:
        return []
    last_pos = ''
    proper_nouns = {'toks': [[]], 'pos': [[]]}
    for i in range(len(sent_toks)):
        pos = sent_toks[i]['pos']
        tok = sent_toks[i]['tok']
        if pos.startswith('NNP'):
            proper_nouns['toks'][-1].append(tok)
            proper_nouns['pos'][-1].append(pos)
        elif len(proper_nouns['toks'][-1]) != 0 and pos in ['IN', 'CC']:
            proper_nouns['toks'][-1].append(tok)
            proper_nouns['pos'][-1].append(pos)
        elif len(proper_nouns['toks'][-1]) != 0:
            if len(proper_nouns['toks'][-1]) == 1:
                proper_nouns['toks'][-1] = []
                proper_nouns['pos'][-1] = []
            elif last_pos not in ['NNP', 'NNPS']:
                proper_nouns['toks'][-1] = proper_nouns['toks'][-1][:-1]
                proper_nouns['pos'][-1] = proper_nouns['pos'][-1][:-1]
                if len(proper_nouns['toks'][-1]) == 1:
                    proper_nouns['toks'][-1] = []
                    proper_nouns['pos'][-1] = []
                else:
                    proper_nouns['toks'].append([])
                    proper_nouns['pos'].append([])
            else:
                proper_nouns['toks'].append([])
                proper_nouns['pos'].append([])
        last_pos = pos
    if len(proper_nouns['toks'][0]) == 0:
        return []
    elif len(proper_nouns['toks'][-1]) == 0:
        proper_nouns['toks'] = proper_nouns['toks'][:-1]
        proper_nouns['pos'] = proper_nouns['pos'][:-1]
    for i in range(len(proper_nouns['toks'])):
        proper_noun = proper_nouns['toks'][i]
        proper_noun = ' '.join(proper_noun)
        proper_noun_lower = proper_noun.lower()
        proper_noun_rate = round(proper_nouns['pos'][i].count('NNP') / len(
            proper_nouns['pos'][i]), 4)
        if proper_noun_lower in container:
            container[proper_noun_lower]['freq'] += 1
        else:
            container[proper_noun_lower] = {'freq': 1, 'raw': proper_noun,
                'nnp_rate': proper_noun_rate}
    return proper_nouns


def bytestobits(bytesource):
    """
    Breaks a given iterable of bytes into an iterable of boolean
    values representing those bytes as unsigned integers.

    >>> [ x for x in bytestobits(b"\\x01\\x30") ]
    [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0]
    """
    for value in bytesource:
        for bitplusone in range(8, 0, -1):
            bitindex = bitplusone - 1
            nextbit = 1 & value >> bitindex
            yield nextbit


def calculate_phases_co2_emissions(cumulative_co2_emissions, phases_distances):
    """
    Calculates the CO2 emission of cycle phases [CO2g/km].

    :param cumulative_co2_emissions:
        Cumulative CO2 of cycle phases [CO2g].
    :type cumulative_co2_emissions: numpy.array

    :param phases_distances:
        Cycle phases distances [km].
    :type phases_distances: numpy.array

    :return:
        CO2 emission of cycle phases [CO2g/km].
    :rtype: numpy.array
    """
    return cumulative_co2_emissions / phases_distances


def _convert_string(text):
    """
    Converts string into more appropriate form for reading and accessing.
    :param text: Text to be converted in a form of string.
    :return: List of strings or a dictionary in dependance of which form is preferable.
    """
    lines = text.split('\n')
    if 'Stack' in text:
        return text.split('\n')
    response = {'header': []}
    for line in lines:
        if line:
            if ':' not in line:
                response['header'].append(line)
            elif ':' in line:
                elements = line.split(':')
                if 'Attachments' in elements[0]:
                    response[elements[1].lstrip()] = elements[2].lstrip()
                else:
                    response[elements[0].lstrip()] = elements[1].lstrip()
    return response


@classmethod
def get_api(cls, pl_user, pl_pass, pl_host, pl_ptn, ec, proxy=None):
    """ Get existing PLCAPI instance

        :param pl_user: Planelab user name (used for web login)
        :type pl_user: str
        :param pl_pass: Planetlab password (used for web login)
        :type pl_pass: str
        :param pl_host: Planetlab registry host (e.g. "www.planet-lab.eu")
        :type pl_host: str
        :param pl_ptn: XMLRPC service pattern (e.g. https://%(hostname)s:443/PLCAPI/)
        :type pl_ptn: str
        :param proxy: Proxy service url
        :type pl_ptn: str
        """
    if pl_user and pl_pass and pl_host:
        key = cls._make_key(pl_user, pl_host)
        with cls._lock:
            api = cls._apis.get(key)
            if not api:
                api = cls.create_api(pl_user, pl_pass, pl_host, pl_ptn, ec,
                    proxy)
            else:
                api.count += 1
            return api
    return None


@classmethod
def _cache_key(cls, *args, **kwargs):
    """A DataSymbol caches on the class type itself."""
    return cls


def _get_compression_for_entry(intake_entry):
    """
    Given an intake catalog entry, determine a compression scheme, if
    applicable. Fiona uses compound protocols like 'zip+s3://' to construct
    paths for GDAL, and we need to construct that properly.

    Returns a string scheme like "zip", "gzip",  or "tar". If no compression
    scheme is used, returns `None`.
    """
    driver = intake_entry.get('driver')
    if (driver == 'shapefile' or driver ==
        'intake_geopandas.geopandas.ShapefileSource'):
        return 'zip'
    else:
        return None


def uniqify(inputList):
    """Uniqifies an inputList and returns outputList"""
    outputList = []
    for item in inputList:
        if not item in outputList:
            outputList.append(item)
    return outputList


@staticmethod
def compose_help_block_message():
    """Assemble a block of relevant help text to be returned with an invalid request."""
    message = 'You must supply a numeric transaction id '
    message += '(like "/transactioninfo/<transaction_id>")'
    return message


def _nonzero_int(integer_string, strict=False, cutoff=None):
    """
    Cast a string to a strictly non-zero integer.
    """
    if integer_string:
        ret = int(integer_string)
    else:
        return integer_string
    if ret == 0 and strict:
        raise ValueError()
    if cutoff:
        return min(ret, cutoff)
    return ret


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

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


def _is_default(a, b):
    """
    Return "Yes" or "No" depending on whether e is the default
    environment or not.
    """
    return 'Yes' if a == b else 'No'


def getParent():
    """Return this member's parent member unique or None if this is the root
        already."""


@staticmethod
def is_shared_block_storage():
    """True if the backend puts images on a shared block storage."""
    return False


def extract_shape(descriptor, key):
    """
    Work around bug in https://github.com/bluesky/ophyd/pull/746
    """
    data_key = descriptor['data_keys'][key]
    if len(data_key['shape']) == 3 and data_key['shape'][-1] == 0:
        object_keys = descriptor.get('object_keys', {})
        for object_name, data_keys in object_keys.items():
            if key in data_keys:
                break
        else:
            raise RuntimeError(f'Could not figure out shape of {key}')
        for k, v in descriptor['configuration'][object_name]['data'].items():
            if k.endswith('num_images'):
                num_images = v
                break
        else:
            num_images = -1
        x, y, _ = data_key['shape']
        shape = num_images, y, x
    else:
        shape = descriptor['data_keys'][key]['shape']
    return shape


def AVID_VIDEO_FORMAT_FROM_WIDTH_HEIGHT(width, height):
    """Utility function to map a width and height to an Avid Project Format"""
    format_map = {'1080': '1080', '720': '720', '576': 'PAL', '486': 'NTSC'}
    mapped = format_map.get(str(height), 'CUSTOM')
    if mapped == '1080' and width > 1920:
        mapped = 'CUSTOM'
    return mapped


def item_activate(extend: bool=True, recursive: bool=False):
    """Handle mouse clicks to activate/select items

    :param extend: Extend, Extend selection for activation
    :type extend: bool
    :param recursive: Recursive, Select Objects and their children
    :type recursive: bool
    """
    pass


@classmethod
def create_from_file(cls, filename):
    """Return an Estimator object given the path of the file, relative to the MEDIA_ROOT"""
    obj = cls()
    obj.object_file = filename
    obj.load()
    return obj


def vec(M):
    """
    Stack columns of M to construct a single vector.

    This is somewhat standard notation in linear algebra.

    Parameters
    ----------
    M : 2d array_like
        Input matrix

    Returns
    -------
    v : 1d ndarray
        Output vector

    """
    return M.T.ravel()


def find_lexeme(verb):
    """ For a regular verb (base form), returns the forms using a rule-based approach.

    taken from pattern.en, because it wouldn't go into py2app properly
    """
    vowels = ['a', 'e', 'i', 'o', 'u']
    v = verb.lower()
    if len(v) > 1 and v.endswith('e') and v[-2] not in vowels:
        return [v, v, v, v + 's', v, v[:-1] + 'ing'] + [v + 'd'] * 6
    if len(v) > 1 and v.endswith('y') and v[-2] not in vowels:
        return [v, v, v, v[:-1] + 'ies', v, v + 'ing'] + [v[:-1] + 'ied'] * 6
    if v.endswith(('ss', 'sh', 'ch', 'x')):
        return [v, v, v, v + 'es', v, v + 'ing'] + [v + 'ed'] * 6
    if v.endswith('ic'):
        return [v, v, v, v + 'es', v, v + 'king'] + [v + 'ked'] * 6
    if len(v) > 1 and v[-1] not in vowels and v[-2] not in vowels:
        return [v, v, v, v + 's', v, v + 'ing'] + [v + 'ed'] * 6
    if len(v) > 1 and v.endswith(('y', 'w')) and v[-2] in vowels or len(v
        ) > 2 and v[-1] not in vowels and v[-2] in vowels and v[-3
        ] in vowels or len(v) > 3 and v[-1] not in vowels and v[-3
        ] in vowels and v[-4] in vowels:
        return [v, v, v, v + 's', v, v + 'ing'] + [v + 'ed'] * 6
    if len(v) > 2 and v[-1] not in vowels and v[-2] in vowels and v[-3
        ] not in vowels:
        return [v, v, v, v + 's', v, v + v[-1] + 'ing'] + [v + v[-1] + 'ed'
            ] * 6
    return [v, v, v, v + 's', v, v + 'ing'] + [v + 'ed'] * 6


@staticmethod
def to_delisle(newton):
    """ Convert newton to delisle """
    return (33 - newton) * 50 / 11


@classmethod
def get_module_title(cls):
    """
        Get human readable name for this blueprint/module.

        :return: Name (short summary) of the blueprint/module.
        :rtype: str
        """
    raise NotImplementedError()


def get_remote_boot_volume(task):
    """Identify a boot volume from any configured volumes.

    :returns: None or the volume target representing the volume.
    """
    targets = task.volume_targets
    for volume in targets:
        if volume['boot_index'] == 0:
            return volume


@staticmethod
def _to_gtk_modifier(key):
    """
        Translates the modifies to the way that GTK likes them.
        """
    key = key.strip()
    if key == 'meta':
        key = '<alt>'
    elif key in ('ctrl', 'alt', 'shift'):
        key = '<' + key + '>'
    else:
        key = key
    return key


def get_instance(app_label, model, pk):
    """Return an instance given its app_label, model name and private key."""
    from django.contrib.contenttypes import models as ct_models
    model = ct_models.ContentType.objects.get(app_label=app_label, model=model)
    return model.get_object_for_this_type(pk=pk)


def full_schedule_to_dict(full_schedule):
    """Generate a dictionary from a schedule object for conversion to JSON.

    Generate a dictionary like:
        { dow: [ {'when': start, 'temp':  {zone: temp}} ] }
    """
    json_schedule = {}
    for dow in range(7):
        json_schedule[dow] = []
    for entry in full_schedule:
        entry_dow, entry_start, entry_zone, entry_temp = entry
        dow = json_schedule[entry_dow]
        entry_start_str = entry_start.strftime('%H:%M')
        added = False
        for e in dow:
            if e['when'] == entry_start_str:
                e['zones'].append({'zone': entry_zone, 'temp': entry_temp})
                added = True
                break
        if not added:
            dow.append({'when': entry_start.strftime('%H:%M'), 'zones': [{
                'zone': entry_zone, 'temp': entry_temp}]})
    return json_schedule


def is_int(string: str) ->bool:
    """Check whether string is integer.
    """
    try:
        int(string)
        return True
    except ValueError:
        return False


@classmethod
def get_article(cls, name):
    """
        Gets an article's info.

        Parameters
        ----------
        name: str
            The name of the Article.

        Returns
        -------
        :class:`Article`
            The article matching the title.
        """
    gen = cls.get_articles([name])
    return next(gen)


@classmethod
def choose_type(cls, content_type):
    """Choose object type from content type."""
    return (cls.type_cls.SUBDIR if content_type in cls.subdir_types else
        cls.type_cls.FILE)


def _merge_args_with_kwargs(args_dict, kwargs_dict):
    """Merge args with kwargs."""
    ret = args_dict.copy()
    ret.update(kwargs_dict)
    return ret


def are_equal_nodes(n1, n2):
    """Returns True if nodes n1 and n2 have the same predicate and sortinfo."""
    return (n1.pred == n2.pred and n1.sortinfo == n2.sortinfo and n1.carg ==
        n2.carg)


def is_sorted(data):
    """
    Checks if given data are sorted ascendantly.

    Args:
        data: (float,)
            Data to check.

    Returns:
        bool
            True if sorted, False otherwise.
    """
    for i in range(data.size - 1):
        if data[i + 1] < data[i]:
            return False
    return True


@classmethod
def from_name(cls, name, fundamental=60, root=(0,)):
    """Initializes a JustLatticeChord from a conventional chord name.

        **Examples**

        >>> JustLatticeChord.from_name('minor triad')
        JustLatticeChord(60 - [1/1, 6/5, 3/2], [5-3-15])

        >>> JustLatticeChord.from_name('major triad', root=(-1, ))
        JustLatticeChord(60 - [4/3, 5/3, 1/1], [1-5-3])
        """
    names = {'sub-minor triad': cls([(1,), (-1, 0, 1)], fundamental, root),
        'minor triad': cls([(1, -1), (1,)], fundamental, root),
        'diminished triad': cls([(1, -1), (0, -1, 1)], fundamental, root),
        'major triad': cls([(0, 1), (1,)], fundamental, root),
        'sub-minor seventh': cls([(-1, 0, 1), (1,), (0, 0, 1)], fundamental,
        root), 'minor seventh': cls([(1, -1), (1,), (2, -1)], fundamental,
        root), 'half-diminished seventh': cls([(1, -1), (0, -1, 1), (2, -1)
        ], fundamental, root), 'major seventh': cls([(0, 1), (1,), (1, 1)],
        fundamental, root), 'super-major seventh': cls([(2, 0, -1), (1,), (
        3, 0, -1)], fundamental, root), 'dominant seventh': cls([(0, 1), (1
        ,), (1, 1), (0, 0, 1)], fundamental, root), 'added second': cls([(0,
        1), (1,), (2, -1)], fundamental, root), 'minor ninth': cls([(1, -1),
        (1,), (2, -1), (2,)], fundamental, root), 'major ninth': cls([(0, 1
        ), (1,), (1, 1), (2,)], fundamental, root), 'dominant ninth': cls([
        (0, 1), (1,), (0, 0, 1), (2,)], fundamental, root), '4-6-7': cls([(
        1,), (0, 0, 1)], fundamental, root), '5-7-9': cls([(0, -1, 1), (2,
        -1)], fundamental, root)}
    try:
        return names[name.lower()]
    except KeyError:
        return NotImplemented


def rax_find_bootable_volume(module, rax_module, server, exit=True):
    """Find a servers bootable volume"""
    cs = rax_module.cloudservers
    cbs = rax_module.cloud_blockstorage
    server_id = rax_module.utils.get_id(server)
    volumes = cs.volumes.get_server_volumes(server_id)
    bootable_volumes = []
    for volume in volumes:
        vol = cbs.get(volume)
        if module.boolean(vol.bootable):
            bootable_volumes.append(vol)
    if not bootable_volumes:
        if exit:
            module.fail_json(msg=
                'No bootable volumes could be found for server %s' % server_id)
        else:
            return False
    elif len(bootable_volumes) > 1:
        if exit:
            module.fail_json(msg=
                'Multiple bootable volumes found for server %s' % server_id)
        else:
            return False
    return bootable_volumes[0]


def GetTransactionCount(block):
    """

    returns the number of transactions in a block

    """
    pass


def get_default_series(config):
    """Return the Juju environment default series.

    Receive the jenv file YAML decoded bootstrap configuration.
    Raise a ValueError is the OS series cannot be found.
    """
    return config.get('default-series', '')


def median(array, *args, **kwargs):
    """
    Computes the median.

    See Also
    --------
    Array.median
    """
    return array.median(*args, **kwargs)


def output_task(name, freq, bins, center):
    """print task information"""
    print('\nTask information:\n')
    if name is 'oto':
        print(
            '                  Parameter name:\tOritentational tetrahedral order'
            )
    if name is 'tto':
        print(
            '                  Parameter name:\tTranslational tetrahedral order'
            )
    if name is 'avc':
        print(
            '                  Parameter name:\tAsphericity of the Voronoi cell'
            )
    if name is 'msd':
        print('                  Parameter name:\tMean square displacement')
    print('                       Frequency:\tevery {:d} frame(s)'.format(freq)
        )
    print('                  Number of bins:\t{:d}'.format(bins))
    if name is not 'msd':
        print('                     Center atom:\t{:s}\n'.format(center))


def generic_find_fk_constraint_names(table, columns, referenced, insp):
    """Utility to find foreign-key constraint names in alembic migrations"""
    names = set()
    for fk in insp.get_foreign_keys(table):
        if fk['referred_table'] == referenced and set(fk['referred_columns']
            ) == columns:
            names.add(fk['name'])
    return names


def indexes_seqsnot(ol, value, seqs):
    """
        from elist.elist import *
        ol = [1,'a',3,'a',4,'a',5]
        indexes_seqsnot(ol,'a',{0,2})
        indexes_seqsnot(ol,'a',{0,1})
        indexes_seqsnot(ol,'a',{1,2})
        indexes_seqsnot(ol,'a',{3,4})
    """
    seqs = list(seqs)
    length = ol.__len__()
    indexes = []
    seq = -1
    for i in range(0, length):
        if value == ol[i]:
            pass
        else:
            seq = seq + 1
            if seq in seqs:
                indexes.append(i)
            else:
                pass
    return indexes


def model_find_module_name(model, module_to_find):
    """Look up the name of a module in a model.

    Arguments:
        model: the model to search
        module_to_find: the module whose name we want to look up

    Returns:
        The module name (string) or None, if the module was not found.
    """
    for name, m in model.named_modules():
        if m == module_to_find:
            return name
    return None


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 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


@classmethod
def simple(cls, sc_points, trans_table, fcr, sc_features=None,
    transmission_costs=None, sort_on='total_lcoe', columns=('trans_gid',
    'trans_type', 'lcot', 'total_lcoe', 'trans_cap_cost'), max_workers=None,
    wind_dirs=None, n_dirs=2, downwind=False):
    """
        Run simple supply curve by connecting to the cheapest tranmission
        feature.

        Parameters
        ----------
        sc_points : str | pandas.DataFrame
            Path to .csv or .json or DataFrame containing supplcy curve
            point summary
        trans_table : str | pandas.DataFrame
            Path to .csv or .json or DataFrame containing supply curve
            transmission mapping
        fcr : float
            Fixed charge rate, used to compute LCOT
        sc_features : str | pandas.DataFrame
            Path to .csv or .json or DataFrame containing additional supply
            curve features, e.g. transmission multipliers, regions
        transmission_costs : str | dict
            Transmission feature costs to use with TransmissionFeatures
            handler: line_tie_in_cost, line_cost, station_tie_in_cost,
            center_tie_in_cost, sink_tie_in_cost
        sort_on : str
            Column label to sort the Supply Curve table on. This affects the
            build priority - connections with the lowest value in this column
            will be built first.
        columns : list | tuple
            Columns to preserve in output supply curve dataframe.
        max_workers : int | NoneType
            Number of workers to use to compute lcot, if > 1 run in parallel.
            None uses all available cpu's.
        wind_dirs : pandas.DataFrame | str
            path to .csv or reVX.wind_dirs.wind_dirs.WindDirs output with
            the neighboring supply curve point gids and power-rose value at
            each cardinal direction
        n_dirs : int, optional
            Number of prominent directions to use, by default 2
        downwind : bool, optional
            Flag to remove downwind neighbors as well as upwind neighbors

        Returns
        -------
        supply_curve : pandas.DataFrame
            Updated sc_points table with transmission connections, LCOT
            and LCOE+LCOT
        """
    sc = cls(sc_points, trans_table, fcr, sc_features=sc_features,
        transmission_costs=transmission_costs, connectable=False,
        max_workers=max_workers)
    supply_curve = sc.simple_sort(sort_on=sort_on, columns=columns,
        wind_dirs=wind_dirs, n_dirs=n_dirs, downwind=downwind)
    return supply_curve


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

        :param SharedLinkRemoveExpiryType val:
        :rtype: EventType
        """
    return cls('shared_link_remove_expiry', val)


@classmethod
def m2m_changed(cls, *args, **kwargs):
    """Adding a hook here so it's safe to call the super's m2m_changed."""
    pass