def subfile_split(value):
    """Split a subfile into the name and payload.

    :param value: The value in the SUBFILE tag.
    :return: (name, data).
    """
    name = value.split(b'\x00', 1)[0].decode('utf-8')
    data = value[128:]
    return name, data


def without_http_prefix(url):
    """
    Returns a URL without the http:// or https:// prefixes
    """
    if url.startswith('http://'):
        return url[7:]
    elif url.startswith('https://'):
        return url[8:]
    return url


def clip(value, minimum, maximum):
    """ Clip a value between two other values. """
    if value < minimum:
        return minimum
    elif value > maximum:
        return maximum
    else:
        return value


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

        :param FileRequestsChangePolicyType val:
        :rtype: EventType
        """
    return cls('file_requests_change_policy', val)


@staticmethod
def _handle_selection(selection):
    """
        Dummy placeholder for returning selection from chooser.
        """
    return selection


def unwrap(url):
    """unwrap('<URL:type://host/path>') --> 'type://host/path'."""
    url = str(url).strip()
    if url[:1] == '<' and url[-1:] == '>':
        url = url[1:-1].strip()
    if url[:4] == 'URL:':
        url = url[4:].strip()
    return url


def patch_click() ->None:
    """Make Click not crash.

    On certain misconfigured environments, Python 3 selects the ASCII encoding as the
    default which restricts paths that it can access during the lifetime of the
    application.  Click refuses to work in this scenario by raising a RuntimeError.

    In case of Black the likelihood that non-ASCII characters are going to be used in
    file paths is minimal since it's Python source code.  Moreover, this crash was
    spurious on Python 3.7 thanks to PEP 538 and PEP 540.
    """
    try:
        from click import core
        from click import _unicodefun
    except ModuleNotFoundError:
        return
    for module in (core, _unicodefun):
        if hasattr(module, '_verify_python3_env'):
            module._verify_python3_env = lambda : None


@classmethod
def from_int(cls, x, length, bitorder='big', *, signed=False):
    """Represent the Python int x as a BitString.
        Acts similarly to int.to_bytes.

        :param int x:
            An integer to represent. Negative integers are represented in two's
            complement form, unless the argument signed is False, in which case
            negative integers raise an OverflowError.

        :param int length:
            The length of the resulting BitString. An OverflowError is raised
            if the integer is not representable in this many bits.

        :param bitorder:
            Determines the bit order used in the BitString representation. By
            default, this function uses Postgres conventions for casting ints
            to bits. If bitorder is 'big', the most significant bit is at the
            start of the string (this is the same as the default). If bitorder
            is 'little', the most significant bit is at the end of the string.

        :param bool signed:
            Determines whether two's complement is used in the BitString
            representation. If signed is False and a negative integer is given,
            an OverflowError is raised.

        :return BitString: A BitString representing the input integer, in the
                           form specified by the other input args.

        .. versionadded:: 0.18.0
        """
    if length < 0:
        raise ValueError('length argument must be non-negative')
    elif length < x.bit_length():
        raise OverflowError('int too big to convert')
    if x < 0:
        if not signed:
            raise OverflowError("can't convert negative int to unsigned")
        x &= (1 << length) - 1
    if bitorder == 'big':
        pass
    elif bitorder == 'little':
        x = int(bin(x)[:1:-1].ljust(length, '0'), 2)
    else:
        raise ValueError("bitorder must be either 'big' or 'little'")
    x <<= -length % 8
    bytes_ = x.to_bytes((length + 7) // 8, byteorder='big')
    return cls.frombytes(bytes_, length)


def noop(*args, **kw):
    """No operation. Returns nothing"""
    pass


def authorize_publication(topic_name, connection):
    """
    Says if a user can publish to a topic or not.
    Return: True or False and the error message ("" if no error occured).
    """
    assert topic_name, 'authorize_publication requires topic_name'
    assert connection, 'authorize_publication requires connection'
    return True, ''


def mass_halliday(df):
    """
    Returns a calculated meteor mass as derived by Halliday and the error in this value. This scheme uses a constant tau
    of 0.04 for meteors with velocities lower than or equal to 36km/s. For velocities greater than this a velocity-
    dependant relationship is used.

    :param df: dataframe containing all processed DAF data
    :return:
    """
    intg_luminosity = 10 ** (-0.39026606 * df['avg_abs_mag'] + 1.96769668
        ) * 2.5
    vel_1 = df.loc[df['vel_avg'] <= 36000, 'vel_avg']
    vel_2 = df.loc[df['vel_avg'] > 36000, 'vel_avg']
    tau_1 = 0.04
    tau_2 = 0.069 * (36 / (vel_2 / 1000)) ** 2
    mass_1 = 2.0 / (tau_1 * vel_1 ** 2) * intg_luminosity
    mass_2 = 2.0 / (tau_2 * vel_2 ** 2) * intg_luminosity
    mass_err_1 = abs(4.0 * tau_1 ** -1 * vel_1 ** -3 * intg_luminosity
        ) * 1 + abs(2.0 * tau_1 ** -1 * vel_1 ** -2 * df['intg_luminosity_err']
        )
    mass_err_2 = abs(4.0 * tau_2 ** -1 * vel_2 ** -3 * intg_luminosity
        ) * 1 + abs(2.0 * tau_2 ** -1 * vel_2 ** -2 * df['intg_luminosity_err']
        )
    mass = mass_1.fillna(mass_2)
    mass_err = mass_err_1.fillna(mass_err_2)
    return mass, mass_err


def type_object_attrgetter(obj, attr, *defargs):
    """
    This implements an improved attrgetter for type objects (i.e. classes)
    that can handle class attributes that are implemented as properties on
    a metaclass.

    Normally `getattr` on a class with a `property` (say, "foo"), would return
    the `property` object itself.  However, if the class has a metaclass which
    *also* defines a `property` named "foo", ``getattr(cls, 'foo')`` will find
    the "foo" property on the metaclass and resolve it.  For the purposes of
    autodoc we just want to document the "foo" property defined on the class,
    not on the metaclass.

    For example::

        >>> class Meta(type):
        ...     @property
        ...     def foo(cls):
        ...         return 'foo'
        ...
        >>> class MyClass(metaclass=Meta):
        ...     @property
        ...     def foo(self):
        ...         ""\"Docstring for MyClass.foo property.""\"
        ...         return 'myfoo'
        ...
        >>> getattr(MyClass, 'foo')
        'foo'
        >>> type_object_attrgetter(MyClass, 'foo')
        <property at 0x...>
        >>> type_object_attrgetter(MyClass, 'foo').__doc__
        'Docstring for MyClass.foo property.'

    The last line of the example shows the desired behavior for the purposes
    of autodoc.
    """
    for base in obj.__mro__:
        if attr in base.__dict__:
            if isinstance(base.__dict__[attr], property):
                return base.__dict__[attr]
            break
    return getattr(obj, attr, *defargs)


@classmethod
def format_name(cls, name):
    """Format op-amp name for use as a key in the data dict.

        Parameters
        ----------
        name : :class:`str`
            The name to format.

        Returns
        -------
        :class:`str`
            The formatted name.
        """
    return str(name).upper()


def _cleanse_wwn(wwn_type, wwn):
    """
    Some wwns may have alternate text representations. Adjust to our
    preferred representation.
    """
    wwn = str(wwn.strip()).lower()
    if wwn_type in ('naa', 'eui', 'ib'):
        if wwn.startswith('0x'):
            wwn = wwn[2:]
        wwn = wwn.replace('-', '')
        wwn = wwn.replace(':', '')
        if not (wwn.startswith('naa.') or wwn.startswith('eui.') or wwn.
            startswith('ib.')):
            wwn = wwn_type + '.' + wwn
    return wwn


def split_local_part(local_part, delimiter=None):
    """Split a local part into local part and extension."""
    assert isinstance(local_part, str), 'local_part should be of type str'
    assert isinstance(delimiter, str
        ) or delimiter is None, 'delimiter should be of type str'
    extension = None
    if local_part.lower() in ['mailer-daemon', 'double-bounce']:
        pass
    elif delimiter == '-' and (local_part.startswith('owner-') or
        local_part.endswith('-request')):
        pass
    elif delimiter and delimiter in local_part and local_part[0
        ] != delimiter and local_part[-1] != delimiter:
        local_part, extension = local_part.split(delimiter, 1)
    return local_part, extension


@staticmethod
def p_a2ml_declaration_list(p):
    """a2ml_declaration_list : a2ml_declaration
                                 | a2ml_declaration a2ml_declaration_list"""
    try:
        p[0] = [p[1]] + p[2]
    except IndexError:
        p[0] = [p[1]]


def CurrentAmplifierThreePort(G, Zi, Zo, Z0=50.0):
    """CurrentAmplifierThreePort
    Three port curent amplifier
    @param G float current gain
    @param Zi float or complex input impedance
    @param Zo float or complex output impedance
    @param Z0 (optional) float reference impedance (defaults to 50 ohms)
    @return list of list s-parameter matrix for a current amplifier
    The three port current amplifier is the same as the four port current amplifier with
    ports two and three connected together and exposed as a single port.

    The current sense element senses the current entering port 3 and exiting port 1
    with a series resistance in the current sense path of Zi.

    The current generated by the amplifier enters port 3 and exits port 2 and is
    shunted with Zo.
    """
    D = 3.0 * Z0 * Z0 + (2.0 * Zo + 2.0 * Zi - G * Zo) * Z0 + Zo * Zi
    S11 = (Zo * Zi + Z0 * (2.0 * Zi - G * Zo) - Z0 * Z0) / D
    S12 = 2.0 * Z0 * Z0 / D
    S13 = (2.0 * Z0 * Z0 + 2.0 * Zo * Z0) / D
    S21 = (2.0 * Z0 * Z0 + 2.0 * G * Zo * Z0) / D
    S22 = (Zo * Zi + Z0 * (2.0 * Zo - G * Zo) - Z0 * Z0) / D
    S23 = (2.0 * Z0 * Z0 + Z0 * (2.0 * Zi - 2.0 * G * Zo)) / D
    S31 = (2.0 * Z0 * Z0 + Z0 * (2.0 * Zo - 2.0 * G * Zo)) / D
    S32 = (2.0 * Z0 * Z0 + 2.0 * Zi * Z0) / D
    S33 = (Zo * Zi - Z0 * Z0 + G * Zo * Z0) / D
    return [[S11, S12, S13], [S21, S22, S23], [S31, S32, S33]]


def shiftxy(posx=0, posy=0):
    """shiftxy(posx=0, posy=0) -> stereo

    Return a two-dimensional stereo shift. If posy is zero (or omitted),
    this is equivalent to shift(posx).
    """
    if posx == 0 and posy == 0:
        return ()
    if posy == 0:
        return 1.0, float(posx)
    return 1.0, float(posx), 1.0, float(posy)


def get_reference(content, name=None, add=False):
    """Retrieve an unique existing reference.
        """


@classmethod
def from_path(cls, path, **kwargs):
    """Create a new graph instance

        Args:
            path(str): the path to basalt database on filesystem.
                The database is created if path does not exists

            kwargs: additional arguments given to the inner graph constructor.
        """
    return cls(path=path, **kwargs)


def BoolProperty(name: str='', description: str='', default=False, options:
    set={'ANIMATABLE'}, subtype: str='NONE', update=None, get=None, set=None):
    """Returns a new boolean property definition.

    :param name: Name used in the user interface.
    :type name: str
    :param description: Text used for the tooltip and api documentation.
    :type description: str
    :param options: Enumerator in [‘HIDDEN’, ‘SKIP_SAVE’, ‘ANIMATABLE’, ‘LIBRARY_EDITABLE’, ‘PROPORTIONAL’,’TEXTEDIT_UPDATE’].
    :type options: set
    :param subtype: Enumerator in [‘PIXEL’, ‘UNSIGNED’, ‘PERCENTAGE’, ‘FACTOR’, ‘ANGLE’, ‘TIME’, ‘DISTANCE’, ‘NONE’].
    :type subtype: str
    :param update: Function to be called when this value is modified, This function must take 2 values (self, context) and return None. Warning there are no safety checks to avoid infinite recursion.
    :param get: Function to be called when this value is ‘read’, This function must take 1 value (self) and return the value of the property.
    :param set: Function to be called when this value is ‘written’, This function must take 2 values (self, value) and return None.
    """
    pass


def rotate_sequence(seq, current):
    """
    Rotates sequence in given index
    :param seq: list
    :param current: int
    :return: list
    """
    n = len(seq)
    for i in range(n):
        yield seq[(i + current) % n]


def tuple_from_sequence(*args):
    """
    Construct a tuple from a sequence (not list!) of objects

    EXAMPLES::

        >>> from openmath.convert_pickle import tuple_from_sequence
        >>> tuple_from_sequence(1, 2, 3)
        (1, 2, 3)
        >>> tuple([1, 2, 3])
        (1, 2, 3)
    """
    return tuple(args)


def get_fips(df):
    """Convert State/County codes to FIPS locations."""
    state = df['STATE'].apply(lambda x: str(x).zfill(2))
    county = df['COUNTY'].apply(lambda x: str(x).zfill(3))
    fips = state + county
    return fips.where(df['COUNTY'].between(1, 996))


def build_no_log_generator(container, log_args):
    """Return a generator that prints a warning about logs and waits for
    container to exit.
    """
    yield "WARNING: no logs are available with the '{}' log driver\n".format(
        container.log_driver)


def _inject_filters(app, filters):
    """Inject a set of filters into a Flask app.

    Args:
        app (object): The Flask application.
        filters (dict): A dictionary of name and functions.

    Returns:
        app (object): The Flask application.
    """
    for name, func in filters.iteritems():
        app.jinja_env.filters[name] = func
    return app


def gen_heading(heading_text, depth=1, alternative=False):
    """Creates a Markdown heading.

    This function creates a heading of the given depth. There
    is also an alternative format for the depth 1 and 2.
    A line break is added to the output.

    Args:
      headingText (string): The name of the heading.
      depth (int): The level (depth) of the heading.
      alternative (bool): If this is set to true and the depth is
        1 or 2 then the alternitive fotmat of headings is used.

    Returns:
      string: The heading text formatted as heading.

    """
    if alternative and depth == 1:
        md_str = heading_text + '\n'
        md_str += '=' * len(heading_text)
        return md_str + '\n'
    if alternative and depth is 2:
        md_str = heading_text + '\n'
        md_str += '-' * len(heading_text)
        return md_str + '\n'
    else:
        md_str = '#' * depth
        md_str += ' '
        md_str += heading_text
        return md_str + '\n'


def create_export_data(export_data, lines):
    """
    Write export data to file.

    export_data - Data to export.
    file_name - Name of the file to write to.

    Returns:
    In place modificaion of lines
    """
    row_string = []
    for value in export_data:
        if isinstance(value, int):
            row_string.append('{0: 7d}'.format(value))
        elif isinstance(value, float):
            row_string.append('{0: 14f}'.format(value))
        else:
            row_string.append('{0:s}'.format(value))
    lines.append('{0}\n'.format('\t'.join(row_string)))


def fetchiter(cursor, arraysize=10000):
    """Generator for cursor results"""
    while True:
        rows = cursor.fetchmany(arraysize)
        print(rows)
        if rows == []:
            break
        for row in rows:
            yield row


def decay_function(value, epoch, reduction_rate):
    """
    Applies to the input value monophonic decay.

    Parameters
    ----------
    value : int, float

    epoch : int
        Current training iteration (epoch).

    reduction_rate : int
        The larger the value the slower decay]
    """
    return value / (1 + epoch / reduction_rate)


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

    Like 'git describe --tags --dirty --always -long'.
    The distance/hash is unconditional.

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


def _is_suitable_activation_layer(model, layer):
    """
    Check whether the layer ``layer`` matches what is required
    by ``model`` to do Grad-CAM on ``layer``.
    Returns a boolean.

    Matching Criteria:
        * Rank of the layer's output tensor.
    """
    rank = len(layer.output_shape)
    required_rank = len(model.input_shape)
    return rank == required_rank


def get_html(pangram):
    """
    Renders the provided pangram in HTML by wrapping it in
 tags.

    Linebreaks are replaced with
 tags.
    """
    html = '
%s
' % pangram
    html = html.replace('\n', '
')
    return html


def OUTPUT(out):
    """Get dictionary serialization for an output object.

    Parameters
    ----------
    out: vizier.viztrail.module.output.OutputObject
        Object in module output stream

    Returns
    -------
    dict
    """
    return {'type': out.type, 'value': out.value}


@classmethod
def get_schema(cls):
    """Returns a dictionary of table schema.

        The dictionary mapping tablenames to the list of column names
        for that table. Both tablenames and columnnames are strings.
        """
    d = {}
    d[cls.OBJECTS] = 'object_id', 'owner_id', 'type'
    d[cls.PARENT_TYPES] = 'id', 'parent_type'
    d[cls.PROPERTIES] = 'owner_id', 'name', 'value'
    d[cls.RELATIONSHIPS] = 'source_id', 'target_id', 'name'
    d[cls.CONNECTED] = 'source_id', 'target_id'
    d[cls.STATES] = 'id', 'state'
    return d


def parse_to_slug(words, maxlen=24):
    """
	Parse a string into a slug format suitable for use in URLs and other
	character restricted applications. Only utf-8 strings are supported at this
	time.

	:param str words: The words to parse.
	:param int maxlen: The maximum length of the slug.
	:return: The parsed words as a slug.
	:rtype: str
	"""
    slug = ''
    maxlen = min(maxlen, len(words))
    for c in words:
        if len(slug) == maxlen:
            break
        c = ord(c)
        if c == 39:
            continue
        elif c >= 48 and c <= 57:
            slug += chr(c)
        elif c >= 65 and c <= 90:
            slug += chr(c + 32)
        elif c >= 97 and c <= 122:
            slug += chr(c)
        elif len(slug) and slug[-1] != '-':
            slug += '-'
    if len(slug) and slug[-1] == '-':
        slug = slug[:-1]
    return slug


def isSecure():
    """
        Return True if this request is using a secure transport.

        Normally this method returns True if this request's HTTPChannel
        instance is using a transport that implements ISSLTransport.

        This will also return True if setHost() has been called
        with ssl=True.

        @returns: True if this request is secure
        @rtype: C{bool}
        """


def _access(cgroups, filesystem):
    """ Access potentially cloud stored files, preserving cgroups
    """
    updated = {}
    for cgroup, paths in cgroups.items():
        updated[cgroup] = filesystem.access(paths)
    return updated


def getid(obj):
    """Return id if argument is a Resource.

    Abstracts the common pattern of allowing both an object or an object's ID
    (UUID) as a parameter when dealing with relationships.
    """
    try:
        if obj.uuid:
            return obj.uuid
    except AttributeError:
        pass
    try:
        return obj.id
    except AttributeError:
        return obj


def encodeName(name):
    """
        Encode the given PDF name

        @param name: A PDFName string to encode
        @return: A tuple (status,statusContent), where statusContent is the encoded PDF name in case status = 0 or an error in case status = -1
    """
    encodedName = ''
    if name[0] == '/':
        name = name[1:]
    for char in name:
        if char == '\x00':
            encodedName += char
        else:
            try:
                hex = '%x' % ord(char)
                encodedName += '#' + hex
            except:
                return -1, 'Error encoding name'
    return 0, '/' + encodedName


@classmethod
def check_qim_dim_match(cls, qim, dim):
    """Check that the given `qim` and `dim` match, i.e. are valid for the
        same index.
        """
    return len(qim) == len(dim)


@staticmethod
def _get_map_cls(map_type):
    """Get map class for given `map_type` string.

        This should probably be a registry dict so that users
        can add supported map types to the `gammapy.maps` I/O
        (see e.g. the Astropy table format I/O registry),
        but that's non-trivial to implement without avoiding circular imports.
        """
    if map_type == 'wcs':
        from .wcsnd import WcsNDMap
        return WcsNDMap
    elif map_type == 'wcs-sparse':
        raise NotImplementedError()
    elif map_type == 'hpx':
        from .hpxnd import HpxNDMap
        return HpxNDMap
    elif map_type == 'hpx-sparse':
        raise NotImplementedError()
    elif map_type == 'region':
        from .regionnd import RegionNDMap
        return RegionNDMap
    else:
        raise ValueError(f'Unrecognized map type: {map_type!r}')


@classmethod
def from_empty(cls):
    """Construct an empty `MatchResult`."""
    return cls(unmatched_segments=(), matched_segments=())


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


def get_constants(module, prefix, named=True, unprefixed=True, valued=True,
    lowercase=True, value_only=False):
    """ Mapping of constants by several ways to specify them """
    result = {}
    for name in dir(module):
        if not name.startswith(prefix):
            continue
        shortname = name[len(prefix):]
        value = getattr(module, name)
        if value_only:
            item = value
        else:
            item = dict(value=value, name=name, shortname=shortname)
        if named:
            result[name] = item
            if lowercase:
                result[name.lower()] = item
        if unprefixed:
            result[shortname] = item
            if lowercase:
                result[shortname.lower()] = item
        if valued:
            result[value] = item
    return result


def _download_sxs_metadata(login, simulations):
    """Download metadata.json from Zenodo for each simulation, if needed"""
    import traceback
    from tqdm.autonotebook import tqdm
    for sxs_id in tqdm(simulations, dynamic_ncols=True):
        download_url = simulations[sxs_id].get('metadata_file_info', {}).get(
            'links', {}).get('download', '')
        if not download_url:
            continue
        try:
            metadata = login.session.get(download_url).json()
            simulations[sxs_id].pop('metadata_file_info', {})
            simulations[sxs_id].update(metadata)
        except KeyboardInterrupt:
            raise
        except:
            traceback.print_exc()


@classmethod
def get_format_string(cls):
    """See RepositoryFormat.get_format_string()."""
    return b'Bazaar Knit Repository Format 4 (bzr 1.0)\n'


def evaluate(context):
    """
        Evaluates a template given a context.

        Returns a pair of headers and parts that can be used to build a MIME
        message.
        """


def summary_table(params, proteins):
    """
    Returns a string representing a simple summary table of
    protein classifcations.
    """
    out = ''
    counts = {}
    for seqid in proteins:
        category = proteins[seqid]['category']
        if category not in counts:
            counts[category] = 1
        else:
            counts[category] += 1
    out += '\n\n# Number of proteins in each class:\n'
    pse_total = 0
    for c in counts:
        if 'PSE-' in c:
            pse_total += counts[c]
    counts['PSE(total)'] = pse_total
    for c in sorted(counts):
        if 'PSE-' in c:
            spacer = '  '
            pse_total += counts[c]
        else:
            spacer = ''
        out += '# %s%-15s\t%i\n' % (spacer, c, counts[c])
    return out


def extended_date_encode(d):
    """ Encodes a date HTML5 (RFC3339) compliant. """
    if not d:
        return ''
    return d.strftime('%Y-%m-%d')


def vert_dissolve(vert: 'bmesh.types.BMVert') ->bool:
    """Dissolve this vertex (will be removed).

    :param vert: The vert to be dissolved.
    :type vert: 'bmesh.types.BMVert'
    :return:  True when the vertex dissolve is successful.
    """
    pass


@classmethod
def RegisterAdditionalConversionType(cls, class_, func):
    """
        This function may be used to register conversions for additional classes, not originally
        treated (e.g.: IGridFunction)

        :param type class_:
            This is the class that should be treated. So, when a conversion is requested,
            if a class is an instance of the class passed, it'll be used to do the conversions.

        :param callable func:
            The function that should do the conversion. It'll be called as
            func(unit_database, quantity_type, from_unit_info, to_unit_info, value)
        """
    if class_ not in cls._additional_conversions:
        cls._additional_conversions[class_] = func
    else:
        assert cls._additional_conversions[class_
            ] == func, 'The class %s already has a convertion function registered' % str(
            class_)


def license(args):
    """Display the mode's LICENSE information."""
    print('Please assist by implementing this command.')


def detect_byte_width(data, num_voxels, silent):
    """
    Detect byte width.

    :param data: Byte string with DF3 body.
    :param num_voxels: Number of voxels in file.
    :param silent: suppress output (info messages, progress etc.)

    """
    byte_width = int(float(len(data)) / num_voxels)
    if not silent:
        plural = ' s'[byte_width > 1]
        print('Voxel resolution: %d byte%s' % (byte_width, plural))
    return byte_width


def _seek_generator(f):
    """Yields seek position for each line.

    Args:
        f (file): the file object

    """
    yield 0
    for line in f:
        yield f.tell()


def prtOptions():
    """Print a list of command-line options and arguments."""
    print('The command-line options are:')
    print('  --version (print the version number and exit)')
    print('  -r (print the full version string and exit)')
    print('  -v (verbose)')
    print('  -t (print timestamps)')
    print('')
    print('Following the options, list one or more input raw file names,')
    print('  enclosed in quotes if more than one file name is specified')
    print('  and/or if wildcards are used.')
    print('One or more output file names may be specified (the same number')
    print('  as the input file names).')


def factory(cls, name, *args, **kwargs):
    """Return an instance of the registered Thing identified by ``name``."""
    klass = cls.get(name)
    if not klass:
        raise KeyError('{} having name {} not found'.format(cls, name))
    return klass(*args, **kwargs)


def unflatten_tree(flattened_tree):
    """Returns the nested tree form described by the given flattened tree

  Inputs:
    flattened_tree - list of tuples. This is the list of tuples returned by the function
                     flatten_tree()

  Returns:
    nested_tree - nested dict. The tree structure in the nested dictionary form.
  """
    nested_tree = {}
    for leaf_tuple in flattened_tree:
        current_node = nested_tree
        leaf_name = leaf_tuple[1][0]
        leaf_value = leaf_tuple[1][1]
        if len(leaf_tuple[0]) > 0:
            full_leaf_path = leaf_tuple[0] + [leaf_name]
            node_0 = full_leaf_path[0]
            for idx in range(1, len(full_leaf_path)):
                node_1 = full_leaf_path[idx]
                if isinstance(node_1, int):
                    if isinstance(current_node, dict
                        ) and node_0 not in current_node.keys():
                        current_node[node_0] = []
                    elif isinstance(current_node, list):
                        current_node.append([])
                elif isinstance(node_1, str):
                    if isinstance(current_node, dict
                        ) and node_0 not in current_node.keys():
                        current_node[node_0] = {}
                    elif isinstance(current_node, list) and node_0 >= len(
                        current_node):
                        current_node.append({})
                current_node = current_node[node_0]
                node_0 = node_1
        if isinstance(current_node, dict):
            current_node[leaf_name] = leaf_value
        else:
            current_node.append(leaf_value)
    return nested_tree


@staticmethod
def get_resource_metadata():
    """Returns the (resource, mime-type) for the handlers spec.
        """
    pass


def theta_Cl_F_MP98(T, P):
    """a-a': chloride fluoride [MP98]."""
    theta = 0.01
    valid = T == 298.15
    return theta, valid


def unpad_array(a, nps):
    """
    Unpads an array using the outputs from pad_array.

    This function takes a padded array and removes the padding from both.
    Effectively, this is a complement to gridder.cut for when you already
    know the number of elements to remove.

    .. note:: Unlike :func:`~fatiando.gridder.pad_array`, this returns a slice
        of the input array.  Therefore, any changes to the padded array will be
        reflected in the unpadded array.

    Parameters:

    * a : array
        Array to be un-padded.  Can be of arbitrary dimension.
    * nps : list
        List of tuples giving the min and max indices for the cutoff.
        Identical to nps returned by pad_array

    Returns:

    * b : array
        Array of same dimension as a, with padding removed

    Examples:

        >>> z = numpy.array([3, 4, 4, 5, 6])
        >>> zpad, nps = pad_array(z)
        >>> zpad
        array([ 4.4,  3.2,  3. ,  4. ,  4. ,  5. ,  6. ,  4.4])
        >>> zunpad = unpad_array(zpad, nps)
        >>> zunpad
        array([ 3.,  4.,  4.,  5.,  6.])

    """
    o = []
    for ii in range(0, a.ndim):
        o.append(slice(nps[ii][0], a.shape[ii] - nps[ii][1]))
    b = a[o]
    return b


def __iter__():
    """ The fanstatic resources to be included
        """


def supersplit(string, separator='', **kwargs):
    """
    like split but can take a list of separators instead of a simple separator
    """
    if not separator:
        return string.split()
    if type(separator) == str:
        return string.split(separator)
    for sep in separator:
        string = string.replace(sep, '#')
    return string.split('#')


def getOrder(context):
    """returns an object implementing the IOrder-interface"""


def createGreat(my_msg='Great stuff!'):
    """
    Useful explanation here for docstrings. Try to follow these conventions:
    https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt#id5
    See the next function as a docs example (taken directly from the IDE
    Spyder).
    """
    great = my_msg
    print(great)
    return great


def cSpmv():
    """
    Return the kernel sources for cSpmv related operations.
    Providing cCSR_spmv_vector and cpELL_spmv_mCoil.
    """
    R = """
        KERNEL void cCSR_spmv_vector(
        const    unsigned int    numRow,
        GLOBAL_MEM const unsigned int *rowDelimiters,
        GLOBAL_MEM const unsigned int *cols,
        GLOBAL_MEM const float2 *val,
        GLOBAL_MEM const float2 *vec,
        GLOBAL_MEM float2 *out)
        {
        const unsigned int t = get_local_id(0);
        const unsigned int vecWidth=${LL};
        // Thread ID within wavefront
        const unsigned int id = t & (vecWidth-1);
        // One row per wavefront
        unsigned int vecsPerBlock=get_local_size(0)/vecWidth;
        unsigned int myRow=(get_group_id(0)*vecsPerBlock) + (t/ vecWidth);
        LOCAL_MEM float2 partialSums[${LL}];
        float2 zero;
        zero.x = 0.0;
        zero.y = 0.0;

        partialSums[t] = zero;
        float2  y= zero;
        if (myRow < numRow)
        {
        const unsigned int vecStart = rowDelimiters[myRow];
        const unsigned int vecEnd = rowDelimiters[myRow+1];
        for (unsigned int j = vecStart+id;  j<vecEnd; j += vecWidth)
        {
        const unsigned int col = cols[j];
        const float2 spdata=val[j];
        const float2 vecdata=vec[col];
        y.x=spdata.x*vecdata.x - spdata.y*vecdata.y;
        y.y=spdata.y*vecdata.x + spdata.x*vecdata.y;
        partialSums[t] = partialSums[t] + y;
        }

        LOCAL_BARRIER;
        //__syncthreads();
        //barrier(CLK_LOCAL_MEM_FENCE);
        // Reduce partial sums
        unsigned int bar = vecWidth / 2;
        while(bar > 0)
        {
        if (id < bar)
        partialSums[t] = partialSums[t] + partialSums[t+bar];

        //barrier(CLK_LOCAL_MEM_FENCE);
        //__syncthreads();
        LOCAL_BARRIER;
        bar = bar / 2;
        }
        // Write result
        if (id == 0)
        {
        out[myRow]=partialSums[t];
        }
        }
        };    // End of cCSR_spmv_vector

        KERNEL void pELL_spmv_mCoil(
        const     unsigned int   Reps,            // Number of coils
        const    unsigned int    nRow,        // number of rows
        const    unsigned int    prodJd,     // product of Jd
        const    unsigned int    sumJd,     // sum of Jd
        const    unsigned int    dim,           // dimensionality
        GLOBAL_MEM const unsigned int *Jd,            // Jd, length = dim
        //GLOBAL_MEM const unsigned int *curr_sumJd,            // summation of Jd[0:dimid]
        GLOBAL_MEM const unsigned int *meshindex,            // meshindex, prodJd * dim
        GLOBAL_MEM const unsigned int *kindx,    // unmixed column indexes of all dimensions
        GLOBAL_MEM const float2 *udata,// interpolation data before Kronecker product
        GLOBAL_MEM const float2 *vec,     // multi-channel kspace data, prodKd * Reps
        GLOBAL_MEM float2 *out)   // multi-channel output, nRow * Reps
        {
        const unsigned int t = get_local_id(0);
        const unsigned int vecWidth=${LL};
        // Thread ID within wavefront
        const unsigned int id = t & (vecWidth-1);

        // One row per wavefront
        unsigned int vecsPerBlock=get_local_size(0)/vecWidth;
        unsigned int myRow=(get_group_id(0)*vecsPerBlock) + (t/ vecWidth); // the myRow-th non-Cartesian sample
        unsigned int m = myRow / Reps;
        unsigned int nc = myRow - m * Reps;
        LOCAL_MEM float2 partialSums[${LL}];
        float2 zero;
        zero.x = 0.0;
        zero.y = 0.0;
        partialSums[t] = zero;

        if (myRow < nRow * Reps)
        {
        const unsigned int vecStart = 0;
        const unsigned int vecEnd =prodJd;
        float2  y;//=zero;

        for (unsigned int j = vecStart+id;  j<vecEnd; j += vecWidth)
        {    // now doing the first dimension
        unsigned int J = Jd[0];
        unsigned int index_shift = m * sumJd ;
        unsigned int index =    index_shift +  meshindex[dim*j + 0];
        unsigned int col = kindx[index] ;
        float2 spdata = udata[index];

        index_shift += J;

        for (unsigned int dimid = 1; dimid < dim; dimid ++ )
        {
        unsigned int J = Jd[dimid];
        unsigned int index =  index_shift + meshindex[dim*j + dimid];   // the index of the partial ELL arrays *kindx and *udata
        col += kindx[index] + 1;                                            // the column index of the current j
        float tmp_x= spdata.x;
        float2 tmp_udata = udata[index];
        spdata.x = spdata.x * tmp_udata.x - spdata.y * tmp_udata.y;                            // the spdata of the current j
        spdata.y = tmp_x * tmp_udata.y + spdata.y * tmp_udata.x;
        index_shift  += J;
        }
        float2 vecdata=vec[col * Reps + nc];
        y.x =  spdata.x*vecdata.x - spdata.y*vecdata.y;
        y.y =  spdata.y*vecdata.x + spdata.x*vecdata.y;
        partialSums[t] = y + partialSums[t];

        }

        LOCAL_BARRIER;

        // Reduce partial sums
        unsigned int bar = vecWidth / 2;
        while(bar > 0)
        {
        if (id < bar)
        partialSums[t]= partialSums[t]+partialSums[t+bar];

        //barrier(CLK_LOCAL_MEM_FENCE);
        //__syncthreads();
        LOCAL_BARRIER;
        bar = bar / 2;
        }
        // Write result
        if (id == 0)
        {
        out[myRow]=partialSums[t];
        }
        }
        };  // End of pELL_spmv_mCoil
        """
    return R


def remove_parenthesis_from_word(sWord):
    """
    Removes parenthesis from words:

        Hello(there) => Hello
        Hello        => Hello

    Parameters:

      sWord: (string)

    Returns: (string)
    """
    if '(' in sWord:
        return sWord.split('(')[0]
    return sWord


def ok_(expr, msg=None):
    """Shorthand for assert. Saves 3 whole characters!
    """
    if not expr:
        raise AssertionError(msg)


def __mul__(A, B):
    """
        * If A,B are TTvec -> Hadamard product of two TT tensors
        * If A TTvec and B scalar -> multiplication by scalar
        """
    C = A.copy()
    C *= B
    return C


def load_time(finder, module):
    """the time module implicitly loads _strptime; make sure this happens."""
    finder.IncludeModule('_strptime')


def buckets(resource):
    """Return all available buckets object."""
    all_buckets = []
    for bucket in resource.buckets.all():
        all_buckets.append(bucket)
    return all_buckets


def is_int(obj):
    """
    True & False is not considered valid integers even if python considers them 1 & 0 in some versions
    """
    return isinstance(obj, int) and not isinstance(obj, bool)


def do_nothing():
    """ Helper function. Does nothing.
    """
    pass


def clear():
    """Clear all grokkers and go back to initial state.
        """


def fixIronPythonExceptionForPickle(exceptionObject, addAttributes):
    """
    Function to hack around a bug in IronPython where it doesn't pickle
    exception attributes. We piggyback them into the exception's args.
    Bug report is at https://github.com/IronLanguages/main/issues/943
    Bug is still present in Ironpython 2.7.7
    """
    if hasattr(exceptionObject, 'args'):
        if addAttributes:
            ironpythonArgs = vars(exceptionObject)
            ironpythonArgs['__ironpythonargs__'] = True
            exceptionObject.args += ironpythonArgs,
        elif len(exceptionObject.args) > 0:
            piggyback = exceptionObject.args[-1]
            if type(piggyback) is dict and piggyback.get('__ironpythonargs__'):
                del piggyback['__ironpythonargs__']
                exceptionObject.args = exceptionObject.args[:-1]
                exceptionObject.__dict__.update(piggyback)


def ge_dsm_precomp(point):
    """
    void ge_dsm_precomp(ge_dsmp r, const ge_p3 *s)
    :param point:
    :return:
    """
    return point


def unpack_single_value_from_df(name, df, allow_empty=True):
    """
    Utility method to unpack a single value from a DataFrame.
    If allow_empty is True (default), an empty DataFrame will be accepted and None will be returned.

    :param name: the name of the DataFrame, for validation purposes
    :param df:
    :param allow_empty:
    :return:
    """
    values = df.values.ravel()
    if len(values) == 1:
        return values[0]
    elif len(values) == 0 and allow_empty:
        return None
    else:
        raise ValueError(
            "DataFrame '%s' is supposed to contain a single value but does not: \n%s"
             % (name, df))


def export_video(clip, op):
    """ Export the clip to a file.

        clip   - clip to export
        out    - absolute path to the resulting file
        fps    - frames per second for the video
        codec  - codec to use for encoding
    """
    clip.write_videofile(op.out, fps=op.fps, codec=op.codec, preset=op.
        preset, threads=op.threads, ffmpeg_params=op.params)


def pop_n(stack, n):
    """Pop n items from the stack.

    If there are less than `n` items in the stack, raise an IndexError.

    .. note:: Code that catches the IndexError, will see the stack empty.

    The items are returned in pop-order: if stack is ``[1, 2, 3, 4]`` and `n`
    is 2, the result would be ``[4, 3]``.

    """
    if len(stack) < n:
        stack[:] = []
        raise IndexError('Popping too many items from the stack')
    items = stack[-n:]
    del stack[-n:]
    items.reverse()
    return items


def parse_address(addr):
    """Parse a socket address.

        >>> parse_address('1234')
        ('localhost', 1234)

        >>> parse_address('example.com:1234')
        ('example.com', 1234)

        >>> parse_address('*:1234')
        ('', 1234)

        >>> try: parse_address('notanumber')
        ... except ValueError as e: print(e)
        Invalid address: notanumber

        >>> try: parse_address('la:la:la')
        ... except ValueError as e: print(e)
        Invalid address: la:la:la

    """
    if ':' in addr:
        try:
            host, port = addr.split(':')
        except ValueError:
            raise ValueError('Invalid address: %s' % addr)
    else:
        host, port = 'localhost', addr
    if host == '*':
        host = ''
    try:
        return host, int(port)
    except ValueError:
        raise ValueError('Invalid address: %s' % addr)


def number_of_plugins_per_risk_factor(report_host, risk_factor_level):
    """
    Function returns number of all plugins reported during scan for given risk factor for given target.
    :param report_host: report host element
    :param risk_factor_level:
        'Critical'
        'High'
        'Medium'
        'Low'
        'None'
    :return: number of plugins for given risk factor
    """
    risk_factor_counter = 0
    for report_item in report_host.findall('ReportItem'):
        risk_factor = report_item.find('risk_factor')
        if risk_factor is not None:
            if risk_factor.text == risk_factor_level:
                risk_factor_counter += 1
    return risk_factor_counter


def fit(model, module, compute_pars=None, data_pars=None, out_pars=None, **
    kwarg):
    """
    Wrap fit generic method
    :type model: object
    """
    return module.fit(model, data_pars, **kwarg)


def rebuild_cache(batch_id, qms):
    """
        Rebuild the cache using the provided IQueryMessageStore implementation.

        :param batch_id:
            The batch identifier for the batch to operate on.

        :param qms:
            An `IQueryMessageStore` provider to rebuild the cache from.

        :returns:
            ``None``.
            If async, a Deferred is returned instead.
        """


def _bool_to_binary(value):
    """
    Turns a Python boolean value (True or False) into binary data.

    This function is suitable for writing to /proc/* and /sys/* files.
    """
    if value is True:
        return b'1'
    if value is False:
        return b'0'
    raise TypeError('Value is not a boolean: %s' % value)


@staticmethod
def _norm_d_pos(observer, target):
    """
        Calculate the normalized position vector between two frames.

        Parameters
        ----------
        observer : `~astropy.coordinates.BaseCoordinateFrame` or `~astropy.coordinates.SkyCoord`
            The observation frame or coordinate.
        target : `~astropy.coordinates.BaseCoordinateFrame` or `~astropy.coordinates.SkyCoord`
            The target frame or coordinate.

        Returns
        -------
        pos_hat : `BaseRepresentation`
            Position representation.
        """
    d_pos = (target.data.without_differentials() - observer.data.
        without_differentials()).to_cartesian()
    dp_norm = d_pos.norm()
    dp_norm.ravel()[dp_norm.ravel() == 0] = 1 * dp_norm.unit
    pos_hat = d_pos / dp_norm
    return pos_hat


def _get_defaults(func):
    """Internal helper to extract the default arguments, by name."""
    code = func.__code__
    pos_count = code.co_argcount
    arg_names = code.co_varnames
    arg_names = arg_names[:pos_count]
    defaults = func.__defaults__ or ()
    kwdefaults = func.__kwdefaults__
    res = dict(kwdefaults) if kwdefaults else {}
    pos_offset = pos_count - len(defaults)
    for name, value in zip(arg_names[pos_offset:], defaults):
        assert name not in res
        res[name] = value
    return res


@classmethod
def ESS(cls, output, target):
    """ Returns the explained sum of squares (ESS).

            :arg output: array of output values
            :arg target: array of target values
        """
    return sum((output - target) ** 2)


def _diff_check_ctxt(check_ctxt, minus_check_ctxt):
    """Removes minus_check_ctxt from check_ctxt"""
    for key in check_ctxt:
        if isinstance(check_ctxt[key], set):
            for warning in minus_check_ctxt[key]:
                if warning in check_ctxt[key]:
                    check_ctxt[key].remove(warning)
        elif isinstance(check_ctxt[key], dict):
            for warning in minus_check_ctxt[key]:
                if warning in check_ctxt[key]:
                    del check_ctxt[key][warning]


def get_shell_cmd(pmconf, rm=False):
    """Form the shell command with the right package manager.
    It must be ready to append the packages list.

    - pmconf: tuple: name of pm, dict with conf (file, pacman, etc).

    Return: a cmd ready to run (str).
    """
    pacman = None
    un_install = 'install'
    if rm:
        un_install = 'uninstall'
    if not pmconf:
        print('Package manager not found. Abort.')
        return 0
    conf = pmconf[1]
    cmd = '{} {} {}'.format(conf.get('sudo', 'sudo'), conf.get('pacman',
        pmconf[0]), conf.get(un_install, un_install))
    return cmd


def clamp_phase(phase):
    """
    Returns phase with all values mapped to between +/- 180 degrees.
    """
    return (phase + 180.0) % 360.0 - 180.0


def getCapitalChargeFactor(interestRate, economicLifetime):
    """ Compute and return capital charge factor (inverse of annuity factor). """
    CCF = 1 / interestRate - 1 / (pow(1 + interestRate, economicLifetime) *
        interestRate)
    CCF = CCF.fillna(economicLifetime)
    return CCF


def getPosition(node):
    """Read position of a phsical or visual object."""
    position = [0.0, 0.0, 0.0]
    positionString = node.getElementsByTagName('origin')[0].getAttribute('xyz'
        ).split()
    position[0] = float(positionString[0])
    position[1] = float(positionString[1])
    position[2] = float(positionString[2])
    return position


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


@staticmethod
def _output_request_type_check(req):
    """Output request type check and ensure list for manipulation.

        Parameters
        ----------
        req : list | tuple | str
            Output request of variable type.

        Returns
        -------
        output_request : list
            Output request.
        """
    if isinstance(req, list):
        output_request = req
    elif isinstance(req, tuple):
        output_request = list(req)
    elif isinstance(req, str):
        output_request = [req]
    else:
        raise TypeError(
            'Output request must be str, list, or tuple but received: {}'.
            format(type(req)))
    return output_request


def hasValidInput():
    """Returns ``True`` is the widget has valid input.

        This method is similar to `hasInput` but it also confirms that the
        input provided by the user can be converted to a valid field value
        based on the field constraints.
        """


@classmethod
def _from_iterable(cls, it):
    """Returns a new iterable instance given the data in 'it'."""
    return cls(data=it)


def replace_text(file_text, substitution_map=None, replacement_map=None):
    """
        a method to replace values in a file text

    :param substitution_map: [optional] dictionary with regex substitution pattern key pairs
    :param replacement_map: [optional] dictionary with replacement text key pairs
    :return: string with text with replacement fields
    """
    import re
    if substitution_map:
        for key, value in substitution_map.items():
            regex_pattern = re.compile(key, re.S)
            file_text = regex_pattern.sub(value, file_text)
    if replacement_map:
        for key, value in replacement_map.items():
            file_text = file_text.replace(key, value)
    return file_text


def set_yggtorrent_tld(yggtorrent_tld=None):
    """
    Redefine all string variable according to new TLD
    """
    global YGGTORRENT_TLD
    global YGGTORRENT_BASE_URL
    global YGGTORRENT_LOGIN_URL
    global YGGTORRENT_SEARCH_URL
    global YGGTORRENT_DOMAIN
    global YGGTORRENT_GET_FILES
    global YGGTORRENT_GET_INFO
    global YGGTORRENT_MOST_COMPLETED_URL
    global YGGTORRENT_FILES_URL
    YGGTORRENT_TLD = yggtorrent_tld
    YGGTORRENT_BASE_URL = f'https://www2.yggtorrent.{YGGTORRENT_TLD}'
    YGGTORRENT_LOGIN_URL = f'{YGGTORRENT_BASE_URL}/user/login'
    YGGTORRENT_SEARCH_URL = f'{YGGTORRENT_BASE_URL}/user/logout'
    YGGTORRENT_SEARCH_URL = f'{YGGTORRENT_BASE_URL}/engine/search?name='
    YGGTORRENT_DOMAIN = '.yggtorrent.gg'
    YGGTORRENT_GET_FILES = f'{YGGTORRENT_BASE_URL}/engine/get_files?torrent='
    YGGTORRENT_GET_INFO = f'https://www2.yggtorrentchg/engine/get_nfo?torrent='
    YGGTORRENT_MOST_COMPLETED_URL = (
        f'{YGGTORRENT_BASE_URL}/engine/mostcompleted')
    YGGTORRENT_FILES_URL = f'{YGGTORRENT_BASE_URL}/engine/get_files?torrent='


@classmethod
def createFromDict(cls, dct):
    """ Create an object of type cls with the dct as the kwargs
        """
    return cls(**dct)


def get_js_parser_res(js_path, func_name, *args):
    """
    python调用js, 并返回结果
    :param js_path: js文件路径
    :param func_name: 待调用的函数名
    :param args: 该函数待传递的参数
    :return: res
    """
    with open(js_path, 'r') as f:
        js_code = f.read()
    js_parser = compile(js_code)
    res = js_parser.call(func_name, *args)
    return res


def get_hbl(A):
    """ Return the half-bottom-left of the given array.
    """
    nx, _ = A.shape
    li = int(nx / 2)
    return A[li:, :li]


def partition_re(string, re):
    """
    Like str.partition(), but uses a regular expression to split contents.
    """
    match = re.search(string)
    if match is None:
        return string, '', ''
    else:
        i, j = match.start(), match.end()
        return string[0:i], string[i:j], string[j:]


@classmethod
def getName(cls):
    """ Class method return the name of the class """
    return cls.__name__


def fisherExactTest(table):
    """Fisher's exact test
	----------
	table: contengency table
	"""
    raise NotImplementedError


def exact_log2(num):
    """Find and return an integer i >= 0 such that num == 2**i.

    If no such integer exists, this function raises ValueError.
    """
    if not isinstance(num, int):
        raise TypeError('unsupported operand type: %r' % (type(num).__name__,))
    n = int(num)
    if n <= 0:
        raise ValueError('cannot compute logarithm of non-positive number')
    i = 0
    while n != 0:
        if n & 1 and n != 1:
            raise ValueError('No solution could be found')
        i += 1
        n >>= 1
    i -= 1
    assert num == 1 << i
    return i


def _is_array(v):
    """
    Returns True if the given value is an Array.

    :param v: the value to check.

    :return: True if the value is an Array, False if not.
    """
    return isinstance(v, list)


def set_preferred_names(catalog):
    """This simply calls the catalog function that performs this task.
    """
    catalog.set_preferred_names()
    return


def do_nothing_function():
    """ This is a do-nothing function, we overwrite the likelihood and prior elsewhere """
    pass


def binomial_mean(n, p):
    """Does what it says it does."""
    return n * p


def get_mysql_autocommit(cn):
    """MySQL autocommit getter for core."""
    return cn.get_autocommit()


def validate_intersection(intersection):
    """Test if the intersection is not empty.
    :returns: bool
    """
    if None in intersection[0]:
        return True
    else:
        return intersection[0].__cmp__(intersection[1]) != 1


def chunkify(iterable, chunksize=10000):
    """Yield successive chunksized chunks from iterable.

    Args:
      iterable:
      chunksize:  (Default value = 10000)

    Returns:

    """
    i = 0
    chunk = []
    for item in iterable:
        chunk.append(item)
        i += 1
        if i == chunksize:
            yield chunk
            i = 0
            chunk = []
    if len(chunk) > 0:
        yield chunk


def lookup():
    """Attempt to resolve an entry in the cache.

        The instance is instructed to look for the cache key that it was
        informed about via the call to ``setcachekey()``.

        If there's no cache hit or the cacher doesn't wish to use the cached
        entry, ``None`` should be returned.

        Else, a dict defining the cached result should be returned. The
        dict may have the following keys:

        objs
           An iterable of objects that should be sent to the client. That
           iterable of objects is expected to be what the command function
           would return if invoked or an equivalent representation thereof.
        """


def _convert_params(sql, params):
    """Convert SQL and params args to DBAPI2.0 compliant format."""
    args = [sql]
    if params is not None:
        if hasattr(params, 'keys'):
            args += [params]
        else:
            args += [list(params)]
    return args


@classmethod
def feature_log_retrieve(cls, project_id):
    """ Retrieve the feature derivation log content and log length for a time series project.

        The Time Series Feature Log provides details about the feature generation process for a
        time series project. It includes information about which features are generated and their
        priority, as well as the detected properties of the time series data such as whether the
        series is stationary, and periodicities detected.

        This route is only supported for time series projects that have finished partitioning.

        The feature derivation log will include information about:

        * | Detected stationarity of the series:
          | e.g. 'Series detected as non-stationary'
        * | Detected presence of multiplicative trend in the series:
          | e.g. 'Multiplicative trend detected'
        * | Detected presence of multiplicative trend in the series:
          | e.g.  'Detected periodicities: 7 day'
        * | Maximum number of feature to be generated:
          | e.g. 'Maximum number of feature to be generated is 1440'
        * | Window sizes used in rolling statistics / lag extractors
          | e.g. 'The window sizes chosen to be: 2 months
          | (because the time step is 1 month and Feature Derivation Window is 2 months)'
        * | Features that are specified as known-in-advance
          | e.g. 'Variables treated as apriori: holiday'
        * | Details about why certain variables are transformed in the input data
          | e.g. 'Generating variable "y (log)" from "y" because multiplicative trend
          | is detected'
        * | Details about features generated as timeseries features, and their priority
          | e.g. 'Generating feature "date (actual)" from "date" (priority: 1)'

        Parameters
        ----------
        project_id : str
            project id to retrieve a feature derivation log for.
        """
    url = 'projects/{}/timeSeriesFeatureLog/file/'.format(project_id)
    response = cls._client.get(url)
    return response.text


def PointerProperty(type=None, name: str='', description: str='', options:
    set={'ANIMATABLE'}, tags: set={}, poll=None, update=None):
    """Returns a new pointer property definition.

    :param type: A subclass of bpy.types.PropertyGroup or bpy.types.ID.
    :param name: Name used in the user interface.
    :type name: str
    :param description: Text used for the tooltip and api documentation.
    :type description: str
    :param options: Enumerator in [‘HIDDEN’, ‘SKIP_SAVE’, ‘ANIMATABLE’, ‘LIBRARY_EDITABLE’, ‘PROPORTIONAL’,’TEXTEDIT_UPDATE’].
    :type options: set
    :param tags: Enumerator of tags that are defined by parent class.
    :type tags: set
    :param poll: function to be called to determine whether an item is valid for this property. The function must take 2 values (self, object) and return Bool.
    :param update: Function to be called when this value is modified, This function must take 2 values (self, context) and return None. Warning there are no safety checks to avoid infinite recursion.
    """
    pass


def get_credentials():
    """
    Returns the value stored in the AWS_ACCESS_KEY_ID environment variable and
    the value stored in the AWS_SECRET_ACCESS_KEY environment variable.

    Returns
    -------
    out : tuple [string]
        The first string of the tuple is the value of the AWS_ACCESS_KEY_ID
        environment variable. The second string of the tuple is the value of the
        AWS_SECRET_ACCESS_KEY environment variable.

    See Also
    --------
    set_credentials
    http://boto.cloudhackers.com/en/latest/boto_config_tut.html

    Examples
    --------
    >>> get_credentials()
    ('RBZH792CTQPP7T435BGQ', '7x2hMqplWsLpU/qQCN6xAPKcmWo46TlPJXYTvKcv')
    """
    from boto.s3.connection import S3Connection
    from boto.exception import NoAuthHandlerFound
    try:
        conn = S3Connection()
    except NoAuthHandlerFound:
        raise RuntimeError(
            'No AWS access credentials found. Please set the environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY or see http://boto.cloudhackers.com/en/latest/boto_config_tut.html for other options in configuring AWS.'
            )
    return conn.access_key, conn.secret_key


def prunecomments(blocks):
    """Remove comments."""
    i = 0
    while i < len(blocks):
        b = blocks[i]
        if b[b'type'] == b'paragraph' and (b[b'lines'][0].startswith(b'.. '
            ) or b[b'lines'] == [b'..']):
            del blocks[i]
            if i < len(blocks) and blocks[i][b'type'] == b'margin':
                del blocks[i]
        else:
            i += 1
    return blocks


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 same_crs(*crs):
    """ Check if multiple CRS are the same

    Parameters
    ----------
    crs : rasterio.crs.CRS
        Multiple CRS to compare

    Returns
    -------
    bool
        True if all of the CRS inputs are the same (according to rasterio)

    See Also
    --------
    osr_same_crs
    """
    assert len(crs) >= 1
    base = crs[0]
    for _crs in crs[1:]:
        if base != _crs:
            return False
    return True


def create_grid(width, height):
    """ Create a two-dimensional grid of specified size. """
    return [[(0) for _x in range(width)] for _y in range(height)]


def default_settings():
    """ Return a *copy* of the dictionary of the default CySCS solver settings.
    """
    stg_default = dict(normalize=True, scale=1.0, rho_x=0.001, max_iters=
        2500, eps=0.001, alpha=1.5, cg_rate=2.0, verbose=True, use_indirect
        =False)
    return stg_default


@staticmethod
def _get_const_multiplier(solution, dmu_code, category):
    """ Helper method that is used for writing input and output data
            to a given output.

            Args:
                solution (Solution): solution.
                dmu_code (str): DMU code.
                category (str): category name.

            Returns:
                int: always returns 1 since we don't need to scale weights.
        """
    return 1


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


@classmethod
def active(cls):
    """
        Return the current active Music object or None if no stream is active.
        """
    return cls._active


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

        :param files.LookupError val:
        :rtype: CreateSharedLinkWithSettingsError
        """
    return cls('path', val)


def p_block_error(p):
    """block : '{' error '}'"""
    print('Syntax error in command block that starts on line %d' % (p.
        lineno(1),))
    raise SyntaxError


@classmethod
def get_defaults(cls, shopify_resource):
    """
        Get a hash of attribute: values that can be used to update or create a local instance of the given Shopify
        resource.
        """
    defaults = {}
    for field in cls.get_default_fields():
        if hasattr(shopify_resource, field):
            defaults[field] = getattr(shopify_resource, field)
    for related_field in cls.get_related_field_names():
        if hasattr(shopify_resource, related_field):
            defaults[related_field + '_id'] = getattr(getattr(
                shopify_resource, related_field), 'id')
        related_field = related_field + '_id'
        if hasattr(shopify_resource, related_field):
            defaults[related_field] = getattr(shopify_resource, related_field)
    return defaults


def str2bool(value):
    """Convert environment variable value to bool."""
    if value is None:
        return False
    else:
        return value.lower() in ('y', 'yes', 'true', '1')


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

    Like 'git describe --tags --dirty --always -long'.
    The distance/hash is unconditional.

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


def vertex_warp(warp_angle: float=6.28319, offset_angle: float=0.0, min:
    float=-1, max: float=1.0, viewmat: float=((0.0, 0.0, 0.0, 0.0), (0.0,
    0.0, 0.0, 0.0), (0.0, 0.0, 0.0, 0.0), (0.0, 0.0, 0.0, 0.0)), center:
    float=(0.0, 0.0, 0.0)):
    """Warp vertices around the cursor

    :param warp_angle: Warp Angle, Amount to warp about the cursor
    :type warp_angle: float
    :param offset_angle: Offset Angle, Angle to use as the basis for warping
    :type offset_angle: float
    :param min: Min
    :type min: float
    :param max: Max
    :type max: float
    :param viewmat: Matrix
    :type viewmat: float
    :param center: Center
    :type center: float
    """
    pass


def _sleep_wake_categorization(data, trend, threshold=0.15):
    """Categorize data as wake (0) or sleep (1)

    If the data are above `thr` % of the trend, they are assigned wake.
    Otherwise, they are assigned sleep.

    Parameters
    ----------
    data : pandas.Series
        Data to categorize

    trend : pandas.Series
        Data with trend

    threshold : int, optional
        Fraction of the trend to use as a threshold for categorization.
        Default is '0.15'.

    Return
    ----------
    sw : pandas.Series
        Categorized data

    """
    sw = (data <= threshold * trend).astype(int)
    return sw.where(trend.notnull())


@staticmethod
def positional_to_model(value):
    """Converts a positional argument to a model value"""
    return value


def dateToInt(date, strfmt='%Y%m%d'):
    """ Converts a datetime date into int
	Parameters:
	-----------
		date : datetime
			date in datetime format
		strfmt : string
			format in which the int date will be generated
	Example:
		dateToInt(dt.date(2015,10,23),'%Y')
	"""
    return int(date.strftime(strfmt))


def is_valid_transaction_hash(tx_hash):
    """Determines if the provided string is a valid Stellar transaction hash.

    :param str tx_hash: transaction hash to check

    :return: True if this is a correct transaction hash
    :rtype: boolean
    """
    if len(tx_hash) != 64:
        return False
    try:
        int(tx_hash, 16)
        return True
    except:
        return False


def restore_redis():
    """Restores the redis client"""
    try:
        from redis.client import Pipeline, Redis
    except ImportError:
        pass
    else:
        if hasattr(Redis.execute_command, '__wrapped__'):
            setattr(Redis, 'execute_command', Redis.execute_command.__wrapped__
                )
        for class_method in ['execute', 'immediate_execute_command']:
            if hasattr(getattr(Pipeline, class_method), '__wrapped__'):
                setattr(Pipeline, class_method, getattr(Pipeline,
                    class_method).__wrapped__)


def TYPE(expression):
    """
    Returns a string that specifies the BSON type of the argument.
    See https://docs.mongodb.com/manual/reference/operator/aggregation/type/
    for more details
    :param expression: The expression or variable
    :return: Aggregation operator
    """
    return {'$type': expression}


@classmethod
def summarize(cls, soup):
    """Take BeautifulSoup and summarize the first paragraph.

        Returns:
            str:

        """
    first_paragraph = soup.find('p').get_text()
    if len(first_paragraph) > cls.SUMMARY_CHARACTER_LIMIT:
        return first_paragraph[:cls.SUMMARY_CHARACTER_LIMIT] + '…'
    else:
        return first_paragraph


def no_log_warn(logical_line):
    """Disallow 'LOG.warn('

    https://bugs.launchpad.net/tempest/+bug/1508442

    C301
    """
    if logical_line.startswith('LOG.warn('):
        yield 0, 'C301 Use LOG.warning() rather than LOG.warn()'


def __str__():
    """Returns an ASCII string with all unicode characters url quoted."""


@classmethod
def from_sphere(klass, sphere, tol=1e-05):
    """Create instance from a Sphere"""
    return klass(theta=sphere.theta, phi=sphere.phi, edges=sphere.edges,
        faces=sphere.faces, tol=tol)


@staticmethod
def _validate_config(config):
    """Validate that the provided configurtion is valid.

        Each dictionary in the configuration list must have the following
        mandatory entries :
            {label: {host(string), port(int), dbpath(string|list of strings)}}
        It can also contain 1 optional key:
            {read_preference(string)}

        Args:
            config: the list of configurations provided at instantiation

        Raises:
            TypeError: a fault in the configurations is found
        """
    if not isinstance(config, list):
        raise TypeError('Config must be a list')
    for config_dict in config:
        if not isinstance(config_dict, dict):
            raise TypeError('Config must be a list of dictionaries')
        label = config_dict.keys()[0]
        cfg = config_dict[label]
        if not isinstance(cfg, dict):
            raise TypeError('Config structure is broken')
        if 'host' not in cfg:
            raise TypeError('Config entries must have a value for host')
        if not isinstance(cfg['host'], str) and not isinstance(cfg['host'],
            list):
            raise TypeError('Host must be a string or a list.')
        if 'port' not in cfg:
            raise TypeError('Config entries must have a value for port')
        if not isinstance(cfg['port'], int):
            raise TypeError('Port must be an int')
        if 'dbpath' not in cfg:
            raise TypeError('Config entries must have a value for dbpath')
        if not isinstance(cfg['dbpath'], str):
            if not isinstance(cfg['dbpath'], list):
                raise TypeError(
                    'Dbpath must either a string or a list of strings')
            for dbpath in cfg['dbpath']:
                if not isinstance(dbpath, str):
                    raise TypeError(
                        'Dbpath must either a string or a list of strings')
        if 'read_preference' in cfg and not isinstance(cfg[
            'read_preference'], str):
            raise TypeError('Read_preference must be a string')
        if 'replicaSet' in cfg and not isinstance(cfg['replicaSet'], str):
            raise TypeError('replicaSet must be a string')


def copy_lookahead(from_parser, to):
    """
    Copy lookahead mode from 'from_parser' to 'to' and return the modified
    parser.
    """
    try:
        to.lookahead = from_parser.lookahead
    except AttributeError:
        pass
    return to


def reshape_array(shape, array, flip_vertically=False, copy=False):
    """Reshape a flat array.

    Examples
    --------
    >>> from landlab.utils.structured_grid import reshape_array
    >>> x = np.arange(12.)
    >>> y = reshape_array((3, 4), x)
    >>> y.shape == (3, 4)
    True
    >>> y
    array([[  0.,   1.,   2.,   3.],
           [  4.,   5.,   6.,   7.],
           [  8.,   9.,  10.,  11.]])
    >>> y.flags['C_CONTIGUOUS']
    True
    >>> x[0] = -1
    >>> y[0, 0]
    -1.0

    >>> x = np.arange(12.)
    >>> y = reshape_array((3, 4), x, flip_vertically=True)
    >>> y
    array([[  8.,   9.,  10.,  11.],
           [  4.,   5.,   6.,   7.],
           [  0.,   1.,   2.,   3.]])
    >>> y.flags['C_CONTIGUOUS']
    False
    >>> x[0] = -1
    >>> y[-1, 0]
    -1.0
    """
    reshaped_array = array.view()
    try:
        reshaped_array.shape = shape
    except ValueError:
        raise
    if flip_vertically:
        flipped_array = reshaped_array[::-1, :]
        if copy:
            return flipped_array.copy()
        else:
            return flipped_array
    elif copy:
        return reshaped_array.copy()
    else:
        return reshaped_array


def is_container(obj, classinfo):
    """ 'obj' is an instance of 'classinfo', but is not a 'str' or 'bytes'
        instance. """
    if isinstance(obj, classinfo) and not isinstance(obj, (str, bytes)):
        return True
    return False


@classmethod
def from_mapping(cls, mapping):
    """Build a :class:`~eodag.config.PluginConfig` from a mapping"""
    c = cls()
    c.__dict__.update(mapping)
    return c


def parse_path(path):
    """
    http://www.w3.org/TR/2014/WD-html-json-forms-20140529/#dfn-steps-to-parse-a-json-encoding-path
    """
    original = path
    failure = [(original, {'last': True, 'type': object})]
    steps = []
    try:
        first_key = path[:path.index('[')]
        if not first_key:
            return original
        steps.append((first_key, {'type': 'object'}))
        path = path[path.index('['):]
    except ValueError:
        return failure
    while path:
        if path.startswith('[]'):
            steps[-1][1]['append'] = True
            path = path[2:]
            if path:
                return failure
        elif path[0] == '[':
            path = path[1:]
            try:
                key = path[:path.index(']')]
                path = path[path.index(']') + 1:]
            except ValueError:
                return failure
            try:
                steps.append((int(key), {'type': 'array'}))
            except ValueError:
                steps.append((key, {'type': 'object'}))
        else:
            return failure
    for i in range(len(steps) - 1):
        steps[i][1]['type'] = steps[i + 1][1]['type']
    steps[-1][1]['last'] = True
    return steps


def no_log_warn(logical_line, filename):
    """Disallow 'LOG.warn('

    """
    if logical_line.startswith('LOG.warn('):
        yield 0, 'P301 Use LOG.warning() rather than LOG.warn()'


def filtered(path, filter):
    """Check if a path is removed by a filter.

    Check if a path is in the provided set of paths, @ref filter. If
    none of the paths in filter begin with @ref path, then True is
    returned to indicate that the path is filtered out. If @ref path is
    longer than the filter, and starts with the filter, it is
    considered unfiltered (all paths below a filter are unfiltered).

    An empty filter ([]) is treated as not filtering any.

    """
    if not filter:
        return False
    for p in filter:
        if len(path) > len(p):
            if path[:len(p)] == p:
                return False
        elif p[:len(path)] == path:
            return False
    return True


def get_java_class(java_class):
    """Returns the java.lang.Class of a JavaClass. This is equivalent to
    calling .class in Java.

    :param java_class: An instance of JavaClass
    :rtype: An instance of JavaObject that corresponds to a java.lang.Class
    """
    return java_class._java_lang_class


def exportName(name):
    """
    Exports a GSSAPI Mechanism Name

    This method "produces a canonical contiguous string representation
    of a mechanism name, suitable for direct comparison for use in
    authorization functions".  The input name must be a valid
    GSSAPI mechanism name, as generated by acceptSecContext or
    canonicalizeName.

    .. note::

       A mechanism name does not, in fact, refer to the name of a
       mechanism.  Instead, it refers to a canonicalized name,
       such as the initiator name returned by acceptSecContext

    :param name: a valid GSSAPI mechanism name
    :returns: a string version of the mechanism name
    :rtype: bytes
    :except GSSError:
    """


@classmethod
def walk_fast(cls, level):
    """Walk along a Hilbert curve at the given level.

        This function does not exist in the SWIG bindings of the original C++
        library. It provides a more Pythonic way to iterate over cells.

        Use with caution: this repeatedly mutates a single instance with a
        changing ``id``. If you save the object, it will change out from
        underneath you.

        :returns:
            Iterator over ids in the same instance of :class:`CellId`.
        """
    instance = cls.begin(level)
    cellid_int = instance.id()
    endid_int = cls.end(level).id()
    increment = instance.lsb() << 1
    while cellid_int != endid_int:
        instance.__id = cellid_int
        yield instance
        cellid_int += increment


def nearest_point_on_line(point, line):
    """Return the nearest point on a line
    """
    return line.interpolate(line.project(point))


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

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


@classmethod
def alter_new_orm_column(cls, orm_col):
    """Allow altering default column attributes when first detected/added

        For instance special column like `__time` for Druid can be
        set to is_dttm=True. Note that this only gets called when new
        columns are detected/created"""
    pass


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

        :param SharedContentChangeViewerInfoPolicyDetails val:
        :rtype: EventDetails
        """
    return cls('shared_content_change_viewer_info_policy_details', val)


def KeyThumb(item):
    """
    Return the key to be used for sorting???
    """
    return item.GetFileName()


def p_declare(p):
    """
    declaration : declare_array
    """
    p[0] = p[1]


@staticmethod
def _get_friends_count(session, user_id):
    """
        https://vk.com/dev/friends.get
        """
    response = session.fetch('friends.get', user_id=user_id, count=1)
    return response['count']


def remove_swarm_metadata(code: bytes) ->bytes:
    """
    Remove swarm metadata from Solidity bytecode
    :param code:
    :return: Code without metadata
    """
    swarm = b'\xa1ebzzr0'
    position = code.find(swarm)
    if position == -1:
        raise ValueError('Swarm metadata not found in code %s' % code.hex())
    return code[:position]


def stack(seq, dim):
    """Stack the sequence of tensors along the given dimension.

    Parameters
    ----------
    seq : list of Tensor
        The tensor sequence.
    dim : int
        The concat dim.

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


def quote(myitem, elt=True):
    """URL encode string"""
    if elt and '<' in myitem and len(myitem) > 24 and myitem.find(']]>') == -1:
        return '<![CDATA[%s]]>' % myitem
    else:
        myitem = myitem.replace('&', '&').replace('<', '<').replace(
            ']]>', ']]>')
    if not elt:
        myitem = myitem.replace('"', '"')
    return myitem


def misidentification_genotype_dict(G, p):
    """
    same misidentification probabilities as misidentification(F,p)
    with prob p(1-p), AA -> aa, aa -> AA, Aa stays the same, B/b stay same
    with prob p(1-p),
    """
    G_new = {}
    n = G.keys()[0]
    G_new.setdefault(n, {})
    for genotypes in G[n].keys():
        G_new[n].setdefault(genotypes, 0.0)
    for genotypes in G[n].keys():
        weight = G[n][genotypes]
        g1, g2, g3, g4, g5, g6, g7, g8 = genotypes
        g9 = n - g1 - g2 - g3 - g4 - g5 - g6 - g7 - g8
        G_new[n][g1, g2, g3, g4, g5, g6, g7, g8] += weight * (1 - 2 * p + p **
            2)
        G_new[n][g7, g8, g9, g4, g5, g6, g1, g2] += weight * p * (1 - p)
        G_new[n][g3, g2, g1, g6, g5, g4, g9, g8] += weight * p * (1 - p)
        G_new[n][g9, g8, g7, g6, g5, g4, g3, g2] += weight * p ** 2
    return G_new


def safeSubtraction(a, b):
    """
    Tries to perform a subtraction: if it doesn't work returns None
    """
    try:
        return a - b
    except:
        return None


def sample(iterable, n_sample):
    """
     Produce a random sample from the list. Pass a number to return n random elements from the list. Otherwise a single random item will be returned.

    CAUTION: Does not yet work with generators
    params: iterable, n_sample
        iterable -> list, sequenece, set, dictionary
        n_sample -> number of random samples to be taken from iterable

    TODO: implement walker's method. current one is too inefficient
    http://code.activestate.com/recipes/576564-walkers-alias-method-for-random-objects-with-diffe/
    Examples:
    >>> _.sample([1, 2, 3, 4, 5, 6])
    >>> [4]
    >>> _.sample([1, 2, 3, 4, 5, 6], 3)
    >>> [1, 6, 2]
    """
    try:
        length = len(iterable)
    except TypeError:
        raise TypeError('sample does not work well with generators')
    import random
    sampled = []
    iterable = list(iterable)
    for i in range(n_sample):
        chosen = random.choice(iterable)
        iterable.remove(chosen)
        sampled.append(chosen)
    return sampled


def test_stereo(azimuths, takeoffs, polarities, sdr=[]):
    """
	Plots points with given azimuths, takeoff angles, and
	polarities on a stereonet. Will also plot both planes
	of a double-couple given a strike/dip/rake
    """
    import matplotlib.pyplot as plt
    import mplstereonet
    from obspy.imaging.beachball import aux_plane
    print('azimuths:')
    print(azimuths)
    print('takeoffs:')
    print(takeoffs)
    print('polarities:')
    print(polarities)
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='stereonet')
    up = polarities > 0
    dn = polarities < 0
    h_rk = ax.rake(azimuths[up] - 90.0 + 180.0, 90.0 - takeoffs[up], 90, 'ro')
    h_rk = ax.rake(azimuths[dn] - 90.0 + 180.0, 90.0 - takeoffs[dn], 90, 'b+')
    print('HERE we ARE')
    if sdr:
        s2, d2, r2 = aux_plane(*sdr)
        h_rk = ax.plane(sdr[0], sdr[1], 'g')
        h_rk = ax.rake(sdr[0], sdr[1], -sdr[2], 'go')
        h_rk = ax.plane(s2, d2, 'g')
        plt.show()


@staticmethod
def depart(spht, _):
    """Append closing tags to document body list."""
    spht.body.append('</div>')


def setDebug(on=True):
    """Function for establising __DEBUG_USER__ to True/False

    Keyword Arguments:
        on {boolean} -- Set's True or False the Debug messages for User Logger calls (default: {True})
    """
    global __DEBUG_USER__
    __DEBUG_USER__ = on


def finalize_output(src):
    """
        finalize_output()
        ________________________________________________________________________

        One of the fonctions required by an output. finalize_output() is
        called after the gathering of all the parts' outputs in order
        to gather all these parts.
        This function is called by musamusa.formats.formats.py::output() .
        ________________________________________________________________________

        ARGUMENT : src = list of ( (str)formatname, data )
                   with, for this format : data = str

        RETURNED VALUE : a string, the final output
    """
    res = []
    for _, data in src:
        res.append(data)
    return ''.join(res)


def toolchain_parser(parser):
    """ Parser for every action that requires a toolchain """
    parser.add_argument('-c', '--config', dest='config', help=
        'Name of a config to use. The config should be associated to a toolchain'
        )
    parser.add_argument('-t', '--toolchain', dest='toolchain_name', help=
        'Name of the toolchain to use')


def istype(obj, check):
    """like isinstance(obj, check), but strict

    This won't catch subclasses.
    """
    if isinstance(check, tuple):
        for cls in check:
            if type(obj) is cls:
                return True
        return False
    else:
        return type(obj) is check


@classmethod
def write_bin(cls, context: str) ->'IoTransferEventArgs':
    """Creates new IoTransferEventArgs of read binary data

		:param context: SCPI command. It is truncated to maximum of 100 characters.
		:return: IoTransferEventArgs object of a write binary data operation."""
    obj = cls(False, False, None, context.rstrip())
    obj.binary = True
    return obj


def get_code_object(obj):
    """Shamelessly borrowed from llpython"""
    return getattr(obj, '__code__', getattr(obj, 'func_code', None))


def get_location(metadata):
    """Get location from ip context metadata."""
    city = metadata['city']
    country = metadata['country']
    country_code = metadata['country_code']
    location = []
    if city:
        location.append('{},'.format(city))
    if country:
        location.append(country)
    if country_code:
        location.append('({})'.format(country_code))
    return ' '.join(location)


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


def attr_has_same_shape(first_obj, second_obj, attr):
    """
    Given two objects, check if the given arraylike attributes of those
    objects have the same shape. If one object has an attribute value of
    ``None``, the other must too.

    Args:
        first_obj (obj): A object with an arraylike ``attr`` attribute.
        second_obj (obj): Another object with an arraylike ``attr`` attribute.
        attr (str): The name of the attribute to test.

    Returns:
        bool: `True` if attributes are the same shape
    """
    first, second = getattr(first_obj, attr), getattr(second_obj, attr)
    if first is None or second is None:
        return first is second
    else:
        return first.shape == second.shape


def exc_info(exception):
    """
    Get exc_info tuple from exception
    """
    return type(exception), exception, exception.__traceback__


def _lemmatize_wrapper_german_germalemma(row, lemmatizer):
    """Wrapper function to lemmatize German texts using ``germalemma`` package."""
    tok, pos = row
    try:
        return lemmatizer.find_lemma(tok, pos)
    except ValueError:
        return tok


def container_def(image, model_data_url=None, env=None, container_mode=None):
    """Create a definition for executing a container as part of a SageMaker model.

    Args:
        image (str): Docker image to run for this container.
        model_data_url (str): S3 URI of data required by this container,
            e.g. SageMaker training job model artifacts (default: None).
        env (dict[str, str]): Environment variables to set inside the container (default: None).
        container_mode (str): The model container mode. Valid modes:
                * MultiModel: Indicates that model container can support hosting multiple models
                * SingleModel: Indicates that model container can support hosting a single model
                This is the default model container mode when container_mode = None
    Returns:
        dict[str, str]: A complete container definition object usable with the CreateModel API if
        passed via `PrimaryContainers` field.
    """
    if env is None:
        env = {}
    c_def = {'Image': image, 'Environment': env}
    if model_data_url:
        c_def['ModelDataUrl'] = model_data_url
    if container_mode:
        c_def['Mode'] = container_mode
    return c_def


def save_ds9(output, filename):
    """Save ds9 region output info filename.

    Parameters
    ----------
    output : str
        String containing the full output to be exported as a ds9 region
        file.
    filename : str
        Output file name.

    """
    ds9_file = open(filename, 'wt')
    ds9_file.write(output)
    ds9_file.close()


@classmethod
def _map_graph(api, defn, path_processor):
    """travel the graph from this element down until we either stop or locate
        a cycle.  each visit occurs within the scope of a root element, forming
        multiple trees as we flatten the graph out.
        """
    api._instrument_read_method(defn, path_processor)
    if defn.create != None or defn.update != None:
        api._instrument_write_or_create_method(defn, path_processor)
    if defn.delete != None:
        api._instrument_delete_method(defn, path_processor)
    for action in defn.actions:
        api._instrument_action(defn, path_processor, action)
    for c_name, c_defn, c_index in defn.collections:
        api._instrument_collection(defn, path_processor.for_child(c_name),
            c_name, c_index)
        api._map_graph(c_defn, path_processor.for_collection(c_name, c_index))
    for s_name, s_defn in defn.scalars:
        api._map_graph(s_defn, path_processor.for_child(s_name))


def build(code, disp=False, retall=False, suggest=True, comments=True,
    vtypes=None, **kws):
    """
Build a token tree out of Matlab code.  This function is used by the other
quick-functions as the first step in code translation.

The function also handles syntax errors in the Matlab code.  It will highlight
the line it crashed on and explain as far as it can why it crashed.

Args:
    code (str): Code to be interpreted
    disp (bool): If true, print out diagnostic information while interpreting.
    retall (bool): If true, return full token tree instead of only code related.
    suggest (bool): If true, suggestion engine will be used to fill in datatypes.
    comments (bool): If true, comments will be striped away from the solution.
    vtypes (dict): Verbatim translations added to tree before process.
    **kws: Additional arguments passed to :py:obj:`~matlab2cpp.Builder`.

Returns:
    Builder,Node: The tree constructor if `retall` is true, else the root node for code.

Example::
    >>> from matlab2cpp.tree import Builder
    >>> builder = matlab2cpp.build("a=4", retall=True)
    >>> print(isinstance(builder, Builder))
    True
    >>> node = matlab2cpp.build("a=4", retall=False)
    >>> print(isinstance(node, collection.Node))
    True
    >>> print(matlab2cpp.build("a**b"))
    Traceback (most recent call last):
        ...
    SyntaxError: File: unamed, line 1 in Matlab code:
    a**b
      ^
    Expected: expression start

See also:
    :py:func:`~matlab2cpp.qtree`,
    :py:class:`~matlab2cpp.Builder`,
    :py:class:`~matlab2cpp.Node`

    """
    from . import supplement, tree
    code = code + '\n\n\n\n'
    if vtypes:
        code = supplement.verbatim.set(vtypes, code)
    builder = tree.builder.Builder(disp=disp, comments=comments, **kws)
    builder.load('unamed', code)
    builder.configure(2 * suggest)
    if retall:
        return builder
    if builder[0][1][0].name == 'main':
        out = builder[0][1][0][3]
        return out
    return builder[0][1]


def local():
    """Barra servida localmente"""


def get_delete_options(defaults=None):
    """Delete-related options

    """
    if defaults is None:
        defaults = {}
    options = {'--ids': {'action': 'store', 'dest': 'delete_list', 'help':
        'Select comma-separated list of resources to be deleted.'},
        '--from-file': {'action': 'store', 'dest': 'delete_file', 'default':
        defaults.get('from_file', None), 'help':
        'Path to a file containing resources ids. One resource per line (e.g., model/50a206a8035d0706dc000376).'
        }, '--source-tag': {'dest': 'source_tag', 'default': defaults.get(
        'source_tag', None), 'help':
        'Select sources tagged with tag to be deleted'}, '--dataset-tag': {
        'dest': 'dataset_tag', 'default': defaults.get('dataset_tag', None),
        'help': 'Select datasets tagged with tag to be deleted'},
        '--model-tag': {'dest': 'model_tag', 'default': defaults.get(
        'model_tag', None), 'help':
        'Retrieve models that were tagged with tag.'}, '--prediction-tag':
        {'dest': 'prediction_tag', 'default': defaults.get('prediction_tag',
        None), 'help': 'Select prediction tagged with tag to be deleted.'},
        '--evaluation-tag': {'dest': 'evaluation_tag', 'default': defaults.
        get('evaluation_tag', None), 'help':
        'Select evaluation tagged with tag to be deleted.'},
        '--ensemble-tag': {'dest': 'ensemble_tag', 'default': defaults.get(
        'ensemble_tag', None), 'help':
        'Select ensemble tagged with tag to be deleted.'},
        '--batch-prediction-tag': {'dest': 'batch_prediction_tag',
        'default': defaults.get('batch_prediction_tag', None), 'help':
        'Select batch prediction tagged with tag to be deleted.'},
        '--anomaly-tag': {'dest': 'anomaly_tag', 'default': defaults.get(
        'anomaly_tag', None), 'help':
        'Select anomaly tagged with tag to be deleted.'},
        '--anomaly-score-tag': {'dest': 'anomaly_score_tag', 'default':
        defaults.get('anomaly_score_tag', None), 'help':
        'Select anomaly score tagged with tag to be deleted.'},
        '--batch-anomaly-score-tag': {'dest': 'batch_anomaly_score_tag',
        'default': defaults.get('batch_anomaly_score_tag', None), 'help':
        'Select batch anomaly score tagged with tag to be deleted.'},
        '--script-tag': {'dest': 'script_tag', 'default': defaults.get(
        'script_tag', None), 'help':
        'Select script tagged with tag to be deleted.'}, '--library-tag': {
        'dest': 'library_tag', 'default': defaults.get('library_tag', None),
        'help': 'Select libraries tagged with tag to be deleted.'},
        '--execution-tag': {'dest': 'execution_tag', 'default': defaults.
        get('execution_tag', None), 'help':
        'Select execution tagged with tag to be deleted.'}, '--all-tag': {
        'dest': 'all_tag', 'default': defaults.get('all_tag', None), 'help':
        'Select resources tagged with tag to be deleted.'}, '--older-than':
        {'action': 'store', 'dest': 'older_than', 'default': defaults.get(
        'older_than', None), 'help':
        'Upper limit to select the resources older than the given number of days, date, or resource.'
        }, '--newer-than': {'action': 'store', 'dest': 'newer_than',
        'default': defaults.get('newer_than', None), 'help':
        'Lower limit to select the resources newer than the given number of days, date, or resource.'
        }, '--cluster-tag': {'dest': 'cluster_tag', 'default': defaults.get
        ('cluster_tag', None), 'help':
        'Retrieve clusters that were tagged with tag.'}, '--centroid-tag':
        {'dest': 'centroid_tag', 'default': defaults.get('centroid_tag',
        None), 'help': 'Retrieve centroids that were tagged with tag.'},
        '--batch-centroid-tag': {'dest': 'batch_centroid_tag', 'default':
        defaults.get('batch_centroid_tag', None), 'help':
        'Retrieve batch centroids that were tagged with tag.'},
        '--topic-model-tag': {'dest': 'topic_model_tag', 'default':
        defaults.get('topic_model_tag', None), 'help':
        'Retrieve topic models that were tagged with tag.'},
        '--linear-regression-tag': {'dest': 'linear_regression_tag',
        'default': defaults.get('linear_regression_tag', None), 'help':
        'Retrieve linear regressions that were tagged with tag.'},
        '--topic-distribution-tag': {'dest': 'topic_distribution_tag',
        'default': defaults.get('topic_distribution_tag', None), 'help':
        'Retrieve topic distributions that were tagged with tag.'},
        '--batch-topic-distribution-tag': {'dest':
        'batch_topic_distribution_tag', 'default': defaults.get(
        'batch_topic_distribution_tag', None), 'help':
        'Retrieve batch topic distributions that were tagged with tag.'},
        '--sample-tag': {'dest': 'sample_tag', 'default': defaults.get(
        'sample_tag', None), 'help':
        'Retrieve samples that were tagged with tag.'}, '--resource-types':
        {'dest': 'resource_types', 'default': defaults.get('resource_types',
        None), 'help': 'Limits the type of resources to be deleted.'},
        '--dry-run': {'action': 'store_true', 'dest': 'dry_run', 'default':
        defaults.get('dry_run', False), 'help':
        'Lists the ids to be deleted, but does not delete.'},
        '--no-dry-run': {'action': 'store_false', 'dest': 'dry_run',
        'default': defaults.get('dry_run', False), 'help':
        'Deletes the ids retrieved to be deleted.'}, '--execution-only': {
        'action': 'store_true', 'dest': 'execution_only', 'default':
        defaults.get('execution_only', False), 'help':
        'Deletes only executions, if present, not generated output resources.'
        }, '--from-dir': {'dest': 'from_dir', 'default': defaults.get(
        'from_dir', None), 'help':
        'Retrieves the ids of the resources logged in the directory to add them to the delete list.'
        }, '--project-tag': {'dest': 'project_tag', 'default': defaults.get
        ('project_tag', None), 'help':
        'Retrieve projects that were tagged with tag.'},
        '--association-tag': {'dest': 'association_tag', 'default':
        defaults.get('association_tag', None), 'help':
        'Retrieve associations that were tagged with tag.'},
        '--logistic-regression-tag': {'dest': 'logistic_regression_tag',
        'default': defaults.get('logistic_regression_tag', None), 'help':
        'Retrieve logistic regression that were tagged with tag.'},
        '--time-series-tag': {'dest': 'time_series_tag', 'default':
        defaults.get('time_series_tag', None), 'help':
        'Retrieve time-series that were tagged with tag.'},
        '--forecast-tag': {'dest': 'forecast_tag', 'default': defaults.get(
        'forecast_tag', None), 'help':
        'Retrieve forecasts that were tagged with tag.'}, '--deepnet-tag':
        {'dest': 'deepnet_tag', 'default': defaults.get('deepnet_tag', None
        ), 'help': 'Retrieve deepnets that were tagged with tag.'},
        '--pca-tag': {'dest': 'pca_tag', 'default': defaults.get('pca_tag',
        None), 'help': 'Retrieve PCA that were tagged with tag.'},
        '--fusion-tag': {'dest': 'fusion_tag', 'default': defaults.get(
        'fusion_tag', None), 'help':
        'Retrieve Fusion that were tagged with tag.'}, '--projection-tag':
        {'dest': 'projection_tag', 'default': defaults.get('projection_tag',
        None), 'help': 'Retrieve projection that were tagged with tag.'},
        '--batch-projection-tag': {'dest': 'batch_projections_tag',
        'default': defaults.get('batch_projections_tag', None), 'help':
        'Retrieve batch projections that were tagged with tag.'},
        '--filter': {'dest': 'filter', 'default': defaults.get('filter',
        None), 'help':
        'Retrieve resources that match the query string filter.'},
        '--status': {'action': 'store', 'default': defaults.get('status',
        'finished'), 'choices': ['finished', 'faulty', 'waiting', 'queued',
        'started', 'in progress', 'summarized', 'uploading', 'unknown',
        'runnable'], 'help':
        'Filter the resources to be deleted by its status (finished if not set).'
        }}
    return options


@classmethod
def __indices_setup__(cls, *args, **kwargs):
    """Extract the object indices from ``kwargs``."""
    return (), ()


@staticmethod
def _around_spans(s, spans):
    """Given a string and spans, return the string around the spans"""
    i = 0
    for start, end in spans:
        if i < start:
            yield s[i:start]
            i = start
        if i < end:
            i = end
    yield s[i:len(s)]


def reverse_key(key):
    """
    Tenant aware function to reverse a cache key.

    Required for django-redis REVERSE_KEY_FUNCTION setting.
    """
    return key.split(':', 3)[3]


def _get_best_indexes(logits, n_best_size):
    """Get the n-best logits from a list."""
    index_and_score = sorted(enumerate(logits), key=lambda x: x[1], reverse
        =True)
    best_indexes = []
    for i in range(len(index_and_score)):
        if i >= n_best_size:
            break
        best_indexes.append(index_and_score[i][0])
    return best_indexes


def refresh_pyconstraints():
    """Refresh all pyconstraints

    """
    pass