@staticmethod
def _traverse_cte(root, vpath_tuple):
    """ Version of the traverse method, that uses a CTE instead of the
        Node.path attribute.  Unfortunately this is **much** slower and works
        only on PostgreSQL.

        It **does** work, but is not used ATM.  Could be very useful to replace
        :func:`kotti.events._set_path_for_new_parent` and
        :func:`kotti.events._set_path_for_new_name` event handlers to handle
        everything on the database with a single call, instead of the expensive
        recursion maassacre we have right now.
        """
    raise NotImplementedError('Use the traverse method instead.')
    """
        # needed until we find out how to pass an empty array of type String
        # (i.e. 'VARCHAR[]') to the initial cte.

        vpath = ('', ) + vpath_tuple

        cte = DBSession.query(
                Node.id,
                # array([concat('', Node.name)]).label('path'))                 concat('', Node.name).label('path'))             .enable_eagerloads(False)             .filter(Node.parent_id == None)             .cte(name="n1", recursive=True)
        parent = aliased(cte, name='parent')
        child = aliased(Node, name='child')
        inner = DBSession.query(
                child.id,
                # (parent.c.path + array([concat('', child.name)])).label('path'))                 concat(parent.c.path, '/', child.name).label('path'))             .enable_eagerloads(False)             .filter(child.parent_id == parent.c.id)
        cte = cte.union_all(inner)
        conditions = [
            # (cte.c.path == array(vpath[:idx + 1]))
            (cte.c.path == '/'.join(vpath[:idx + 1]))
            for idx, item in enumerate(vpath)]
        ids = DBSession.query(Node.id.label('node_id'))             .select_entity_from(cte)             .filter(or_(*conditions))
        nodes = DBSession.query(Node).filter(Node.id.in_(ids)).order_by(Node.path).offset(1).all()
        for i, node in enumerate(nodes):
            if i == 0:
                setattr(node, 'parent', root)
            else:
                setattr(node, 'parent', nodes[i-1])
        return nodes
        """


def find_set_selected():
    """Find specified text and set as selected

    """
    pass


def __new__(cls, *args, **kwargs):
    """ Create a new ArgumentSink, with arbitrary positional
            and/or keyword arguments
        """
    instance = super().__new__(cls)
    instance.args = args
    instance.kwargs = kwargs
    return instance


@classmethod
def from_dict(cls, data):
    """
        Alternate constructor which deciphers raw DynamoDB request data before
        ultimately calling regular ``__init__`` method.

        See :py:meth:`__init__` for more insight.

        :param data: raw DynamoDB request data.

        :return: fully initialized :py:class:`Key` instance
        """
    return cls(data[u'AttributeName'], data[u'AttributeType'])


def formula_2009_01_01(foyer_fiscal, period, parameters):
    """
        Renvoie la liste des charges déductibles avant rbg_int pour 2009
        """
    pensions_alimentaires_deduites = foyer_fiscal(
        'pensions_alimentaires_deduites', period)
    cd_acc75a = foyer_fiscal('cd_acc75a', period)
    cd_deddiv = foyer_fiscal('cd_deddiv', period)
    cd_eparet = foyer_fiscal('cd_eparet', period)
    grosses_reparations = foyer_fiscal('grosses_reparations', period)
    niches1 = (pensions_alimentaires_deduites + cd_acc75a + cd_deddiv +
        cd_eparet + grosses_reparations)
    return niches1


def maybe_unroll_group(g):
    """Unroll group with only one member."""
    try:
        size = len(g.tasks)
    except TypeError:
        try:
            size = g.tasks.__length_hint__()
        except (AttributeError, TypeError):
            return g
        else:
            return list(g.tasks)[0] if size == 1 else g
    else:
        return g.tasks[0] if size == 1 else g


def batch_get_image(registryId=None, repositoryName=None, imageIds=None,
    acceptedMediaTypes=None):
    """
    Gets detailed information for specified images within a specified repository. Images are specified with either imageTag or imageDigest .
    See also: AWS API Documentation

    Examples
    This example obtains information for an image with a specified image digest ID from the repository named ubuntu in the current account.
    Expected Output:

    :example: response = client.batch_get_image(
        registryId='string',
        repositoryName='string',
        imageIds=[
            {
                'imageDigest': 'string',
                'imageTag': 'string'
            },
        ],
        acceptedMediaTypes=[
            'string',
        ]
    )

    :type registryId: string
    :param registryId: The AWS account ID associated with the registry that contains the images to describe. If you do not specify a registry, the default registry is assumed.

    :type repositoryName: string
    :param repositoryName: [REQUIRED]
            The repository that contains the images to describe.

    :type imageIds: list
    :param imageIds: [REQUIRED]
            A list of image ID references that correspond to images to describe. The format of the imageIds reference is imageTag=tag or imageDigest=digest .
            (dict) --An object with identifying information for an Amazon ECR image.
            imageDigest (string) --The sha256 digest of the image manifest.
            imageTag (string) --The tag used for the image.

    :type acceptedMediaTypes: list
    :param acceptedMediaTypes: The accepted media types for the request.
            Valid values: application/vnd.docker.distribution.manifest.v1+json | application/vnd.docker.distribution.manifest.v2+json | application/vnd.oci.image.manifest.v1+json
            (string) --

    :rtype: dict
    :return: {
        'images': [
            {
                'registryId': 'string',
                'repositoryName': 'string',
                'imageId': {
                    'imageDigest': 'string',
                    'imageTag': 'string'
                },
                'imageManifest': 'string'
            },
        ],
        'failures': [
            {
                'imageId': {
                    'imageDigest': 'string',
                    'imageTag': 'string'
                },
                'failureCode': 'InvalidImageDigest'|'InvalidImageTag'|'ImageTagDoesNotMatchDigest'|'ImageNotFound'|'MissingDigestAndTag',
                'failureReason': 'string'
            },
        ]
    }

    """
    pass


def __call__(request):
    """
        Toolbar per-request authorization.

        Should return bool values whether toolbar is permitted to monitor
        the provided request.

        """


def select_border(gesture_mode: int=0, xmin: int=0, xmax: int=0, ymin: int=
    0, ymax: int=0, extend: bool=True):
    """Activate/select the file(s) contained in the border

    :param gesture_mode: Gesture Mode
    :type gesture_mode: int
    :param xmin: X Min
    :type xmin: int
    :param xmax: X Max
    :type xmax: int
    :param ymin: Y Min
    :type ymin: int
    :param ymax: Y Max
    :type ymax: int
    :param extend: Extend, Extend selection instead of deselecting everything first
    :type extend: bool
    """
    pass


def configure(conf):
    """
	Detect the luac compiler and set *conf.env.LUAC*
	"""
    conf.find_program('luac', var='LUAC')


@staticmethod
def internal_attrs():
    """Returns a list of internal attributes.

        Internal attributes can't be added, replaced or removed. This
        method may be overwritten by derived class.

        """
    return ['/created_at', '/id', '/links', '/updated_at', '/uuid']


@staticmethod
def update(src, dst):
    """Perform a simple update."""
    for key in src.keys():
        dst[key] = src[key]


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 cast_hex(s):
    """Cast a string value to a hex integer.

    Args:
        s (str): String to cast.

    Returns:
        int: Base 16 integer for provided string.

    """
    return int(s, 16)


def text_input(text):
    """
    Ask the user for textual input.

    Parameters
    ----------
    text : str
        What the user sees.

    Returns
    -------
    inputed_text : str
        What the user wrote.
    """
    return input(text)


def lin_norm_row_by_row(data):
    """
    Normalize data with linear algorithm but
    instead to normalize all the matrix, the normalization formula
    (see :func:`normalize`) is applied row by row.
    It ensure that all values are between 0 and 1.

    :param data: the data to normalize, this 2D matrix must contains only coverage scores (no more metadata).
    :type data: a 2D :class:`pandas.DataFrame` object.
    :return: a normalize matrix, where  0 <= zi <=1 where z=(z1, ..., zn)
    :rtype: a 2D :class:`pandas.DataFrame` object or None if data is None.
    """
    if data is None or data.empty:
        return data
    norm_data = data.sub(data.min(axis=1), axis=0)
    amplitude = data.max(axis=1) - data.min(axis=1)
    norm_data = norm_data.div(amplitude, axis=0)
    return norm_data


def update():
    """We use the content provider update/render couple.
        """


def theta_Mg_Na_PK74(T, P):
    """c-c': magnesium sodium [PK74]."""
    theta = 0.0
    valid = T == 298.15
    return theta, valid


def get_resources(PaginationToken=None, TagFilters=None, ResourcesPerPage=
    None, TagsPerPage=None, ResourceTypeFilters=None):
    """
    Returns all the tagged resources that are associated with the specified tags (keys and values) located in the specified region for the AWS account. The tags and the resource types that you specify in the request are known as filters . The response includes all tags that are associated with the requested resources. If no filter is provided, this action returns a paginated resource list with the associated tags.
    See also: AWS API Documentation

    :example: response = client.get_resources(
        PaginationToken='string',
        TagFilters=[
            {
                'Key': 'string',
                'Values': [
                    'string',
                ]
            },
        ],
        ResourcesPerPage=123,
        TagsPerPage=123,
        ResourceTypeFilters=[
            'string',
        ]
    )

    :type PaginationToken: string
    :param PaginationToken: A string that indicates that additional data is available. Leave this value empty for your initial request. If the response includes a PaginationToken , use that string for this value to request an additional page of data.

    :type TagFilters: list
    :param TagFilters: A list of tags (keys and values). A request can include up to 50 keys, and each key can include up to 20 values.
            If you specify multiple filters connected by an AND operator in a single request, the response returns only those resources that are associated with every specified filter.
            If you specify multiple filters connected by an OR operator in a single request, the response returns all resources that are associated with at least one or possibly more of the specified filters.
            (dict) --A list of tags (keys and values) that are used to specify the associated resources.
            Key (string) --One part of a key-value pair that make up a tag. A key is a general label that acts like a category for more specific tag values.
            Values (list) --The optional part of a key-value pair that make up a tag. A value acts as a descriptor within a tag category (key).
            (string) --

    :type ResourcesPerPage: integer
    :param ResourcesPerPage: A limit that restricts the number of resources returned by GetResources in paginated output. You can set ResourcesPerPage to a minimum of 1 item and the maximum of 50 items.

    :type TagsPerPage: integer
    :param TagsPerPage: A limit that restricts the number of tags (key and value pairs) returned by GetResources in paginated output. A resource with no tags is counted as having one tag (one key and value pair).
            GetResources does not split a resource and its associated tags across pages. If the specified TagsPerPage would cause such a break, a PaginationToken is returned in place of the affected resource and its tags. Use that token in another request to get the remaining data. For example, if you specify a TagsPerPage of 100 and the account has 22 resources with 10 tags each (meaning that each resource has 10 key and value pairs), the output will consist of 3 pages, with the first page displaying the first 10 resources, each with its 10 tags, the second page displaying the next 10 resources each with its 10 tags, and the third page displaying the remaining 2 resources, each with its 10 tags.
            You can set TagsPerPage to a minimum of 100 items and the maximum of 500 items.

    :type ResourceTypeFilters: list
    :param ResourceTypeFilters: The constraints on the resources that you want returned. The format of each resource type is service[:resourceType] . For example, specifying a resource type of ec2 returns all tagged Amazon EC2 resources (which includes tagged EC2 instances). Specifying a resource type of ec2:instance returns only EC2 instances.
            The string for each service name and resource type is the same as that embedded in a resource's Amazon Resource Name (ARN). Consult the AWS General Reference for the following:
            For a list of service name strings, see AWS Service Namespaces .
            For resource type strings, see Example ARNs .
            For more information about ARNs, see Amazon Resource Names (ARNs) and AWS Service Namespaces .
            (string) --

    :rtype: dict
    :return: {
        'PaginationToken': 'string',
        'ResourceTagMappingList': [
            {
                'ResourceARN': 'string',
                'Tags': [
                    {
                        'Key': 'string',
                        'Value': 'string'
                    },
                ]
            },
        ]
    }

    """
    pass


def _stringify_path(path_or_buffer):
    """Convert path like object to string

    Args:
        path_or_buffer: object to be converted

    Returns:
        string_path_or_buffer: maybe string version of path_or_buffer
    """
    try:
        import pathlib
        _PATHLIB_INSTALLED = True
    except ImportError:
        _PATHLIB_INSTALLED = False
    if hasattr(path_or_buffer, '__fspath__'):
        return path_or_buffer.__fspath__()
    if _PATHLIB_INSTALLED and isinstance(path_or_buffer, pathlib.Path):
        return str(path_or_buffer)
    return path_or_buffer


def match_token(token, tok_type, tok_str=None):
    """Returns true if token is of the given type and, if a string is given, has that string."""
    return token.type == tok_type and (tok_str is None or token.string ==
        tok_str)


@classmethod
def hdrtxt(cls):
    """Construct tuple of status display column title."""
    return ('Itn',) + cls.hdrtxt_objfn + ('Rsdl', 'F', 'Q', 'It_Bt', 'L')


def splat(obj):
    """ Ensure that the object is always a list """
    if obj is None:
        return None
    if isinstance(obj, (list, set, tuple)):
        return list(obj)
    return [obj]


def default_response(verb):
    """
    reasonable default response
    """
    if verb == 'post':
        return {'201': {'description': 'success'}}
    if verb in ('patch', 'delete', 'put'):
        return {'204': {'description': 'success'}}
    return {'200': {'description': 'api result'}}


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


def glUseProgram(program: int):
    """Installs a program object as part of current rendering state

    :param program: Specifies the handle of the program object whose executables are to be used as part of current rendering state.
    :type program: int
    """
    pass


def multi1(vals):
    """
    This will either return the common value from a list of identical values
    or the single character '?'
    """
    uniq_vals = list(set(vals))
    num_vals = len(uniq_vals)
    if num_vals == 0:
        return None
    if num_vals == 1:
        return uniq_vals[0]
    if num_vals > 1:
        return '?'


@classmethod
def from_query_select(Class, xml, asof=None):
    """Find or instantiate an object and fill it with data that just came back from query"""
    idref = xml.get('id')
    data = Class._v1_v1meta.unpack_asset(xml)
    instance = Class._v1_v1meta.asset_from_oid(idref)
    instance.AsOf = asof
    data['AsOf'] = asof
    return instance.with_data(data)


def __enter__():
    """Support for the context manager protocol"""


def rgb(red, green, blue):
    """
    Return the string HTML representation of the color
    in 'rgb(red, blue, green)' format.

    :param red:   0 <= int <= 255
    :param green: 0 <= int <= 255
    :param blue:  0 <= int <= 255

    :return: str
    """
    assert isinstance(red, int)
    assert 0 <= red < 256
    assert isinstance(green, int)
    assert 0 <= green < 256
    assert isinstance(blue, int)
    assert 0 <= blue < 256
    return 'rgba(%d, %d, %d)' % (red, green, blue)


def dec2hex(num, positions=2, base=16):
    """ Like chr(), but as string """
    retval = ''
    chars = '0123456789ABCDEF'
    for count in range(positions - 1, -1, -1):
        value = base ** count
        digit = chars[int(num / value)]
        retval += digit
        num -= int(num / value) * value
    return retval


@staticmethod
def _calc_cost(distance, line_cost=3667, tie_in_cost=0,
    transmission_multiplier=1):
    """
        Compute transmission cost in $/MW

        Parameters
        ----------
        distance : float
            Distance to feature in miles
        line_cost : float
            Cost of tranmission lines in $/MW-mile
        tie_in_cost : float
            Cost to connect to feature in $/MW
        line_multiplier : float
            Multiplier for region specific line cost increases

        Returns
        -------
        cost : float
            Cost of transmission in $/MW
        """
    cost = distance * line_cost * transmission_multiplier + tie_in_cost
    return cost


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

        :param LegalHoldsExportCancelledType val:
        :rtype: EventType
        """
    return cls('legal_holds_export_cancelled', val)


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


@classmethod
def set_debug(cls, on=True):
    """
        sets debugging on or of

        :param on: if on debugging is set
        :return:
        """
    cls.debug = on


def _common_idxs(reference, site):
    """
    Finds overlapping indexes from two DataFrames.
    Coverage is 1 if whole site data is covered. Also returns the number data points
    """
    common = reference.index.intersection(site.index)
    return common, len(common)


def get_sector_size(partition):
    """Return the sector size of a partition.
    Used by disk_io_counters().
    """
    try:
        with open('/sys/block/%s/queue/hw_sector_size' % partition, 'rt') as f:
            return int(f.read())
    except (IOError, ValueError):
        return 512


def validate_bytes_type(value, byte_len, err_msg):
    """Checks that the serialized value is a valid byte string.
    Args:
        value       (bytes):          value to check
        byte_len  list(int):          valid byte lengths
        err_msg       (str):          error message
    Returns:
        (True):                       if value is valid, otherwise error
    """
    if not isinstance(value, bytes) or len(value) not in byte_len:
        raise ValueError(err_msg)
    return True


def _revision_arg(value):
    """
    Validates the value of the optional revision argument.

    :raises ValueError: If revision number is invalid.
    :param value: Argument value.
    :return: Validated value.
    """
    if value == 'head':
        return 0
    value = int(value)
    if value >= 0:
        return value
    raise ValueError("Must be 'head' or an integer >= 0.")


def _is_descriptor(obj):
    """Returns True if obj is a descriptor, False otherwise."""
    return hasattr(obj, '__get__') or hasattr(obj, '__set__') or hasattr(obj,
        '__delete__')


@classmethod
def bind_path_name_to_access_point(cls, access_point, path_name):
    """
        Bind the pathname with the access point.

        Example
            Given :code:`https://example.org` as :code:`access_point`
            and :code:`/orgs/list` as :code:`path_name`, we return
            :code:`https://example.org/orgs/list`.

        :param str access_point: The access point to bind :code:`path_name` with.
        :param str path_name: The path name to bind to :code:`access_point`.

        :rtype: str
        """
    if not isinstance(path_name, str):
        path_name = str(path_name)
    if not path_name.startswith('http'):
        if access_point.endswith('/'):
            if path_name.startswith('/'):
                path_name = path_name[1:]
        elif not path_name.startswith('/'):
            path_name = f'/{path_name}'
        return access_point + path_name
    return path_name


@classmethod
def underline(cls, s):
    """Wrap text in underline."""
    return cls._wrap_colour(s, cls.UNDERLINE)


def is_iterable(x):
    """An implementation independent way of checking for iterables."""
    try:
        iter(x)
    except TypeError:
        return False
    else:
        return True


def is_iter(something):
    """
    Helper vectorized function to test
    if something is an iterable other
    than a str.
    """
    try:
        iter(something)
        return True and not isinstance(something, str)
    except TypeError:
        return False


def empty_hash(hashes):
    """
    Determines the hash of an empty file. We do
    this just to be sure that, should they change
    the hashing mechanism, we continue to work.
    """
    for h, groups in hashes.items():
        if groups[0]['size'] == 0:
            return h
    return None


def get_shape(bdg, iwu_bdg, a_ref):
    """
    Takes the IWU reference building and scales its shape such
     that it fits the given reference area

    :param bdg: Dictionary with the relevant parameters
    :param iwu_bdg: IWU-Reference building as dictionary
    :param a_ref: float
    :return: bdg
    """
    bdg['A_ref'] = a_ref
    ratio = a_ref / iwu_bdg['A_C_Ref']
    bdg['n_Storey'] = iwu_bdg['n_Storey']
    bdg['h_room'] = iwu_bdg['h_room']
    for di in ['North', 'East', 'South', 'West']:
        bdg['A_Window_' + di] = iwu_bdg['A_Window_' + di] * ratio ** 0.5
    bdg['A_Window_Horizontal'] = iwu_bdg['A_Window_Horizontal'
        ] * ratio / iwu_bdg['n_Storey']
    bdg['A_Window'] = sum(bdg['A_Window_' + di] for di in ['North', 'East',
        'South', 'West', 'Horizontal'])
    bdg['F_sh_vert'] = iwu_bdg['F_sh_vert']
    bdg['F_sh_hor'] = iwu_bdg['F_sh_hor']
    bdg['F_f'] = iwu_bdg['F_f']
    bdg['F_w'] = iwu_bdg['F_w']
    for wall in ['Wall_1', 'Wall_2', 'Wall_3']:
        bdg['A_' + wall] = iwu_bdg['A_' + wall] * ratio ** 0.5
    for roof in ['Roof_1', 'Roof_2']:
        bdg['A_' + roof] = iwu_bdg['A_' + roof] * (1 + (ratio - 1) /
            iwu_bdg['n_Storey'])
    for floor in ['Floor_1', 'Floor_2']:
        bdg['A_' + floor] = iwu_bdg['A_' + floor] * (1 + (ratio - 1) /
            iwu_bdg['n_Storey'])
    for door in ['Door_1']:
        bdg['A_' + door] = iwu_bdg['A_' + door] * ratio ** 0.5
    return bdg


def put_retention_policy(logGroupName=None, retentionInDays=None):
    """
    Sets the retention of the specified log group. A retention policy allows you to configure the number of days you want to retain log events in the specified log group.
    See also: AWS API Documentation

    :example: response = client.put_retention_policy(
        logGroupName='string',
        retentionInDays=123
    )

    :type logGroupName: string
    :param logGroupName: [REQUIRED]
            The name of the log group.

    :type retentionInDays: integer
    :param retentionInDays: [REQUIRED]
            The number of days to retain the log events in the specified log group. Possible values are: 1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1827, and 3653.

    """
    pass


def end_frame_set():
    """Set the current frame as the preview or scene end frame

    """
    pass


def dolly(delta: int=0, mx: int=0, my: int=0):
    """Dolly in/out in the view

    :param delta: Delta
    :type delta: int
    :param mx: Zoom Position X
    :type mx: int
    :param my: Zoom Position Y
    :type my: int
    """
    pass


def add_imicrobe_subparser(subparser):
    """
    Function to add a subparser for the iMicrobe repository.
    """
    parser_imicrobe = subparser.add_parser('imicrobe', help=
        'download from iMicrobe')
    parser_imicrobe.add_argument('imicrobeid', type=str, nargs='+', help=
        'One or more iMicrobe project or sample identifiers (p##/s###)')
    parser_imicrobe.add_argument('-m', dest='metadata', type=str, default=
        '', help=
        'filename in which to save metadata (.csv format, relative to OUTDIR)')
    parser_imicrobe.add_argument('-o', dest='outdir', type=str, default='',
        help="directory in which to save output. created if it doesn't exist")
    parser_imicrobe.add_argument('-r', dest='retries', type=int, default=0,
        help='number of times to retry download')
    parser_imicrobe.add_argument('-t', dest='threads', type=int, default=1,
        help='threads to use (for pigz)')
    parser_imicrobe.add_argument('-f', dest='force', action='store_true',
        help='force re-download of files')
    parser_imicrobe.add_argument('-l', dest='list', action='store_true',
        help='list (but do not download) samples to be grabbed')


def snap_selected_to_active():
    """Snap selected item(s) to the active item

    """
    pass


def _escape_for_regex(text):
    """Escape ``text`` to allow literal matching using egrep"""
    re_specials = '\\^$|(){}[]*+?.'
    sh_specials = '\\$`"'
    re_chars = []
    sh_chars = []
    for c in text:
        if c == '\n':
            continue
        if c in re_specials:
            re_chars.append('\\')
        re_chars.append(c)
    for c in re_chars:
        if c in sh_specials:
            sh_chars.append('\\')
        sh_chars.append(c)
    return ''.join(sh_chars)


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

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

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


def fib(n):
    """Fibonacci example function

    Args:
      n (int): integer

    Returns:
      int: n-th Fibonacci number
    """
    assert n > 0
    a, b = 1, 1
    for i in range(n - 1):
        a, b = b, a + b
    return a


def __len__():
    """Return the number of history records."""


def get_name(img, map_name):
    """Returns name of cache file."""
    import os
    if img._pi:
        pi_text = 'pi'
    else:
        pi_text = 'I'
    suffix = '/w%i_%s/' % (img.j, pi_text)
    dir = img.tempdir + suffix
    if not os.path.exists(dir):
        os.makedirs(dir)
    return dir + map_name + '.bin'


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


def 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 perm_switch(p1, p2, i, j):
    """
    Exchanges the values at positions ``i`` and ``j`` in two permutations
    ``p_1`` and ``p_2``.

    EXAMPLES::

        sage: from surface_dynamics.misc.permutation import perm_switch
        sage: a = [0,1,2]
        sage: b = [1,2,0]
        sage: perm_switch(a,b,0,1)
        sage: a;b
        [1, 0, 2]
        [2, 1, 0]
    """
    i1 = p1[i]
    j1 = p1[j]
    p1[i] = j1
    p1[j] = i1
    i2 = p2[i1]
    j2 = p2[j1]
    p2[i1] = j2
    p2[j1] = i2


def decode(packet):
    """
    https://github.com/telldus/telldus/blob/master/telldus-core/service/ProtocolFineoffset.cpp

    >>> decode(dict(data=0x48801aff05))["data"]["temp"]
    2.6
    """
    data = packet['data']
    data = '%010x' % int(data)
    data = data[:-2]
    humidity = int(data[-2:], 16)
    data = data[:-2]
    value = int(data[-3:], 16)
    temp = (value & 2047) / 10
    value >>= 11
    if value & 1:
        temp = -temp
    data = data[:-3]
    id = int(data, 16) & 255
    if humidity <= 100:
        return dict(packet, model='temperaturehumidity', sensorId=id, data=
            dict(humidity=humidity, temp=temp))
    else:
        return dict(packet, model='temperature', sensorId=id, data=dict(
            temp=temp))


def dprint(name, val):
    """Debug print name and val."""
    from pprint import pformat
    print('% 5s: %s' % (name, '\n       '.join(pformat(val, indent=4, width
        =75).split('\n'))))


@staticmethod
def _get_key_second_half(platform):
    """Get the key corresponding to the platform number.

        Returns:
             key_second_half(str): Representative submits tasks to several
                platforms.

        """
    setting_mappings = {'2': 'www2', '3': 'www3', '6': 'www6', '20': 'pic',
        '21': 'gpu'}
    return setting_mappings[platform]


@staticmethod
def is_feedlike_url(url: str) ->bool:
    """
        Return True any part of URL might identify as feed.

        :param url: URL string
        :return: bool
        """
    return any(map(url.lower().count, ['rss', 'rdf', 'xml', 'atom', 'feed',
        'json']))


def multigraph_paths(G, source, cutoff=None):
    """
    For a networkx MultiDiGraph, find all paths from a source node
    to leaf nodes. This function returns edge instance numbers
    in addition to nodes, unlike networkx.all_simple_paths.

    Parameters
    ---------------
    G : networkx.MultiDiGraph
      Graph to evaluate
    source : hashable
      Node to start traversal at
    cutoff : int
      Number of nodes to visit
      If None will visit all nodes

    Returns
    ----------
    traversals : (n,) list of [(node, edge instance index), ] paths
      Traversals of the multigraph
    """
    if cutoff is None:
        cutoff = len(G.edges()) * len(G.nodes()) + 1
    current = [(source, 0)]
    queue = []
    traversals = []
    for i in range(cutoff):
        current_node = current[-1][0]
        child = G[current_node]
        if len(child) == 0:
            traversals.append(current)
            if len(queue) == 0:
                break
            current = queue.pop()
        else:
            start = True
            for node in child.keys():
                for instance in child[node].keys():
                    if start:
                        current.append((node, instance))
                        start = False
                    else:
                        queue.append(current[:-1] + [(node, instance)])
    return traversals


def _sauce_ondemand_url(saucelabs_user, saucelabs_key):
    """Get sauce ondemand URL for a given user and key."""
    return 'http://{0}:{1}@ondemand.saucelabs.com:80/wd/hub'.format(
        saucelabs_user, saucelabs_key)


def load_zope_component(finder, module):
    """the zope.component package requires the presence of the pkg_resources
       module but it uses a dynamic, not static import to do its work."""
    finder.IncludeModule('pkg_resources')


def boolean(s):
    """
    Convert JSON/Swagger boolean value to Python, raise ValueError otherwise

    >>> boolean('true')
    True

    >>> boolean('false')
    False
    """
    if isinstance(s, bool):
        return s
    elif not hasattr(s, 'lower'):
        raise ValueError('Invalid boolean value')
    elif s.lower() == 'true':
        return True
    elif s.lower() == 'false':
        return False
    else:
        raise ValueError('Invalid boolean value')


def group_edit(exit: bool=False):
    """Edit node group

    :param exit: Exit
    :type exit: bool
    """
    pass


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

        :param TeamFolderMetadata val:
        :rtype: TeamFolderArchiveLaunch
        """
    return cls('complete', val)


def parseCommandLineArguments(cmdLine):
    """Parses command line arguments provided by the user in the UI"""
    result = []
    cmdLine = cmdLine.strip()
    expectQuote = False
    expectDblQuote = False
    lastIndex = len(cmdLine) - 1
    argument = ''
    index = 0
    while index <= lastIndex:
        if expectQuote:
            if cmdLine[index] == "'":
                if cmdLine[index - 1] != '\\':
                    if argument != '':
                        result.append(argument)
                        argument = ''
                    expectQuote = False
                else:
                    argument = argument[:-1] + "'"
            else:
                argument += cmdLine[index]
            index += 1
            continue
        if expectDblQuote:
            if cmdLine[index] == '"':
                if cmdLine[index - 1] != '\\':
                    if argument != '':
                        result.append(argument)
                        argument = ''
                    expectDblQuote = False
                else:
                    argument = argument[:-1] + '"'
            else:
                argument += cmdLine[index]
            index += 1
            continue
        if cmdLine[index] == "'":
            if index == 0 or cmdLine[index - 1] != '\\':
                expectQuote = True
                if argument != '':
                    result.append(argument)
                    argument = ''
            else:
                argument = argument[:-1] + "'"
            index += 1
            continue
        if cmdLine[index] == '"':
            if index == 0 or cmdLine[index - 1] != '\\':
                expectDblQuote = True
                if argument != '':
                    result.append(argument)
                    argument = ''
            else:
                argument = argument[:-1] + '"'
            index += 1
            continue
        if cmdLine[index] in (' ', '\t'):
            if argument != '':
                result.append(argument)
                argument = ''
            index += 1
            continue
        argument += cmdLine[index]
        index += 1
    if argument != '':
        result.append(argument)
    if expectQuote or expectDblQuote:
        raise Exception('No closing quotation')
    return result


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


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

        :param PaperContentAddMemberDetails val:
        :rtype: EventDetails
        """
    return cls('paper_content_add_member_details', val)


def single_number(nums):
    """
    Returns single number, if found.
    Else if all numbers appear twice, returns 0.
    :type nums: List[int]
    :rtype: int
    """
    i = 0
    for num in nums:
        i ^= num
    return i


def default_ack(last_sent_diction):
    """
    The default fucntion called when network receives an ack after sending something.
    This function is totally unnecessary.... mostly for debugging but maybe
    it will be useful someday to overwrite this with something
    :param last_sent_diction: dict
    """
    pass


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

        :param FileRequestReceiveFileType val:
        :rtype: EventType
        """
    return cls('file_request_receive_file', val)


def union(c1, c2):
    """Compute the Union of c1 and c2.

        If c1 is None, then c2 is returned, otherwise, if c2 is None,
        then c1 is returned.

        The output is a Set containing keys from the input
        collections.
        """


def extract_channel_events(channel, maxdur=0.012, thresh=0.2, samplerate=44100
    ):
    """From a single channel, extract events that reach *thresh*old and last
    for *maxdur*"""
    events = []
    lastevt = -20000
    for index, value in enumerate(channel):
        if index - lastevt > maxdur * samplerate:
            if abs(value) > thresh:
                events.append(index / samplerate)
                lastevt = index
    return events


@classmethod
def get_converter(cls, in_type, out_type):
    """
        @param::in_type: the input datafram type in string
        @param::out_type: the output datafram type in string
        return the converter class that can perform the dataframe conversion
        """
    for c in cls.__converters__:
        if c.is_capable(in_type, out_type):
            return c


def normalize_str(string: str) ->str:
    """
    Normalize a string by applying on it lowercase and replacing '-' to '_'.
    >>> normalize_str("Content-Type")
    'content_type'
    >>> normalize_str("X-content-type")
    'x_content_type'
    """
    return string.lower().replace('-', '_')


def systemd_coredump_enabled():
    """Returns True if kernel.core_pattern sysctl invokes systemd-coredump"""
    with open('/proc/sys/kernel/core_pattern', 'rt') as f:
        text = f.read()
        return text.startswith('|') and 'systemd-coredump' in text


def handle_extension(environ, resource_name):
    """
    Look for an extension (as defined in :py:mod:`config <tiddlyweb.config>`)
    on the provided ``resource_name`` and trim it off to give the
    "real" resource name.
    """
    extension = environ.get('tiddlyweb.extension')
    extension_types = environ['tiddlyweb.config']['extension_types']
    if extension and extension in extension_types:
        try:
            resource_name = resource_name[0:resource_name.rindex('.' +
                extension)]
        except ValueError:
            pass
    else:
        try:
            del environ['tiddlyweb.extension']
        except KeyError:
            pass
    return resource_name


def read_var_length(fp):
    """ take a file pointer that will presumably read characters from the
    pointed-to file, and return a numeric value. """
    output = 0
    inbyte = ord(fp.read(1))
    output = inbyte & 127
    while inbyte & 128 == 128:
        inbyte = ord(fp.read(1))
        output = (output << 7) + (inbyte & 127)
    return output


@classmethod
def from_object(cls, obj):
    """Construct a curve from an existing Rhino curve object.

        Parameters
        ----------
        obj : Rhino.DocObjects.CurveObject
            The Rhino curve object.

        Returns
        -------
        curve : compas_rhino.geometry.RhinoCurve
            The wrapped curve.
        """
    curve = cls()
    curve.guid = obj.Id
    curve.object = obj
    curve.geometry = obj.Geometry
    return curve


def _octant_coord(octant, x0, y0, x, y):
    """Return symmetrically reflected coordinates for a given pair."""
    if octant == 7:
        return x0 + x, y0 + y
    elif octant == 0:
        return x0 + x, y0 - y
    elif octant == 4:
        return x0 - x, y0 + y
    elif octant == 3:
        return x0 - x, y0 - y
    elif octant == 6:
        return x0 + y, y0 + x
    elif octant == 1:
        return x0 + y, y0 - x
    elif octant == 5:
        return x0 - y, y0 + x
    elif octant == 2:
        return x0 - y, y0 - x


def slv_to_uint(slv):
    """
    Convert a string of '0' and '1' to an unsigned integer.

    >>> slv_to_uint('001')
    1
    >>> slv_to_uint('1010')
    10
    """
    total = 0
    f = 1
    for ch in reversed(slv):
        if ch not in ('0', '1'):
            total = None
        if total is not None:
            if ch == '1':
                total += f
            f *= 2
    return total


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

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


def dispatch_hook(key, hooks, hook_data, **kwargs):
    """Dispatches a hook dictionary on a given piece of data."""
    hooks = hooks or dict()
    hooks = hooks.get(key)
    if hooks:
        if hasattr(hooks, '__call__'):
            hooks = [hooks]
        for hook in hooks:
            _hook_data = hook(hook_data, **kwargs)
            if _hook_data is not None:
                hook_data = _hook_data
    return hook_data


@staticmethod
def __find_clause(query, clause):
    """
        checks if a sparql query already has some clause. Useful when trying to batch retrieve the results
        :param query: the sparql query string
        :return: -1 if the clause does not exist or the range of the number after the clause
        """
    clause = ' {} '.format(clause.strip().lower())
    query = query.lower().replace('\n', ' ')
    pos = query.find(clause)
    if pos == -1:
        return -1, -1
    else:
        i = pos + len(clause)
        while i < len(query) and query[i].isdigit():
            i += 1
        return pos + len(clause), i


def convert_conditions(conditions):
    """
    Convert the conditions to a mapping of nodename->list of conditions.
    """
    if conditions is None:
        return {}
    res = {}
    if 'attributes' in conditions:
        for condition in conditions['attributes']:
            cond = condition[0]
            node = condition[1][0]
            attr = condition[1][1]
            if node in res:
                res[node].append((cond, attr))
            else:
                res[node] = [(cond, attr)]
    if 'compositions' in conditions:
        for condition in conditions['compositions']:
            cond = condition[0]
            if cond in ['same', 'diff']:
                for item in condition[1]:
                    node = item
                    if node in res:
                        res[node].append((cond, [item for item in condition
                            [1] if item != node][0]))
                    else:
                        res[node] = [(cond, [item for item in condition[1] if
                            item != node][0])]
            else:
                for item in condition[1][1]:
                    node = item
                    attr = condition[1][0]
                    if node in res:
                        res[node].append((cond, (attr, [item for item in
                            condition[1] if item != node])))
                    else:
                        res[node] = [(cond, (attr, [item for item in
                            condition[1] if item != node]))]
    return res


def escape_triple_quotes(text):
    """
    Escape triple-quotes, used for multi-line text/doc-strings.
    """
    return text.replace(u'"""', u'\\"\\"\\"')


def splitline(text):
    """
    Splits the given text at newline.

        >>> splitline('foo\\nbar')
        ('foo\\n', 'bar')
        >>> splitline('foo')
        ('foo', '')
        >>> splitline('')
        ('', '')
    """
    index = text.find('\n') + 1
    if index:
        return text[:index], text[index:]
    else:
        return text, ''


def van_der_corput(n_sample, base=2, start_index=0):
    """Van der Corput sequence.

    Pseudo-random number generator based on a b-adic expansion.

    Parameters
    ----------
    n_sample : int
        Number of element of the sequence.
    base : int
        Base of the sequence.
    start_index : int
        Index to start the sequence from.

    Returns
    -------
    sequence : list (n_samples,)
        Sequence of Van der Corput.
    """
    sequence = []
    for i in range(start_index, start_index + n_sample):
        n_th_number, denom = 0.0, 1.0
        quotient = i
        while quotient > 0:
            quotient, remainder = divmod(quotient, base)
            denom *= base
            n_th_number += remainder / denom
        sequence.append(n_th_number)
    return sequence


def restrictedTraverse(path, default=None):
    """Trusted code traversal code, always enforces security.
        """


def stripper(name):
    """
    Strip fluff from bar filename.

    :param name: Bar filename, must contain '-nto+armle-v7+signed.bar'.
    :type name: str
    """
    return name.replace('-nto+armle-v7+signed.bar', '')


def neg_left(data):
    """
    Negate left half.
    """
    data[(...), 0:int(data.shape[-1] / 2.0)] = -data[(...), 0:int(data.
        shape[-1] / 2.0)]
    return data


def _can_int(char):
    """check if a character can be turned into an integer"""
    try:
        int(char)
        return True
    except ValueError:
        return False


@classmethod
def from_address(cls, address):
    """Creates and address object from an address string"""
    return cls(address=address)


def iacorr(data, t=None, n=None, norm=0, method='corr', count=None,
    chunk_size=None, thread_divisor=None, auto_background=False, viewer=
    None, viewer_interval=1, mode='full', mask=None, stats=True):
    """Iterative version of :func:`ccorr`

    Parameters
    ----------
    data : iterable
        An iterable object, iterating over single-frame ndarray data.
    t : int or array-like, optional
        Array of integers defining frame times of the data. If it is a scalar
        it defines the length of the input data
    n : int, optional
        Determines the length of the output (max time delay - 1 by default).
    norm : int, optional
        Specifies normalization procedure 0,1,2, or 3 (default).
    method : str, optional
        Either 'fft', 'corr' or 'diff'. If not given it is chosen automatically based on
        the rest of the input parameters.
    chunk_size : int
        Length of data chunk.
    count : int, optional
        If given, it defines how many elements of the data to process. If not given,
        count is set to len(t1) if that is not specified, it is set to len(data).
    thread_divisor : int, optional
        If specified, input frame is reshaped to 2D with first axis of length
        specified with the argument. It defines how many treads are run. This
        must be a divisor of the total size of the frame. Using this may speed
        up computation in some cases because of better memory alignment and
        cache sizing.
    auto_background : bool
        Whether to use data from first chunk to calculate and subtract background.
    viewer : any, optional
        You can use :class:`.viewer.MultitauViewer` to display data.
    viewer_interval : int, optional
        A positive integer, defines how frequently are plots updated 1 for most
        frequent, higher numbers for less frequent updates.
    mode : str
        Either "full" or "partial". With mode = "full", output of this function
        is identical to the output of :func:`ccorr_multi`. With mode = "partial",
        cross correlation between neigbouring chunks is not computed.
    mask : ndarray, optional
        If specifed, computation is done only over elements specified by the mask.
        The rest of elements are not computed, np.nan values are written to output
        arrays.
    stats : bool
        Whether to return stats as well.

    Returns
    -------
    acorr_data, bg, var : acorr_type, ndarray, ndarray
        Acorr data, background and variance data. See :func:`acorr` for definition
        of acorr_type
    acorr_data : acorr_type
        If `stats` == False
    """
    period = 1
    nlevel = 0
    from cddm.multitau import _compute_multi_iter, _VIEWERS
    for i, mdata in enumerate(_compute_multi_iter(data, t, period=period,
        level_size=n, chunk_size=chunk_size, method=method, count=count,
        auto_background=auto_background, nlevel=nlevel, norm=norm,
        thread_divisor=thread_divisor, mode=mode, mask=mask, stats=stats,
        cross=False)):
        if stats == True:
            (data, dummy), bg, var = mdata
        else:
            data, dummy = mdata
        if viewer is not None:
            if i == 0:
                _VIEWERS['acorr'] = viewer
            if i % viewer_interval == 0:
                if stats == True:
                    viewer.set_data(data, background=bg, variance=var)
                    viewer.plot()
                else:
                    viewer.set_data(data)
                    viewer.plot()
    if stats == True:
        return data, bg, var
    else:
        return data


def set_dict_arg(key, arg, line_dim_obj, artists, legend_handles=None):
    """Helper for artist-sepcific matplotlib kwargs"""
    set_attr_name = 'set_' + key
    for dim_index, value in arg.items():
        index = line_dim_obj._array_index(dim_index)
        if isinstance(index, int):
            key_artists = [artists[index]]
        else:
            key_artists = artists[index]
        if not key_artists:
            continue
        for artist in key_artists:
            getattr(artist, set_attr_name)(value)
        if legend_handles is not None:
            for artist in key_artists:
                artist.set_label(dim_index)
            legend_handles[dim_index] = artist


@staticmethod
def is_multivalue(field_name):
    """
        Check, if given form field is a multivalue field.

        :param str field_name: Name of the form field.
        :return: ``True``, if the field can contain multiple values, ``False`` otherwise.
        :rtype: bool
        """
    if field_name in ('source_addrs', 'target_addrs', 'host_addrs',
        'source_ports', 'target_ports', 'host_ports', 'source_types',
        'target_types', 'host_types', 'detectors', 'detector_types',
        'categories', 'severities', 'classess', 'protocols', 'groups',
        'inspection_errs'):
        return True
    return False


def none_or_is_callable(instance, attribute, value):
    """
    Can be None or callable.
    """
    if value is not None and not callable(value):
        raise TypeError('callback must be a callable, got %s' % type(value)
            .__name__)


def indebug(ui, message):
    """debug on input stream (unbundling)"""
    if ui.configbool(b'devel', b'bundle2.debug'):
        ui.debug(b'bundle2-input: %s\n' % message)


def remove_unsynchronization(data):
    """Remove ID3v2 unsynchronization scheme from data."""
    sync_index = data.find(b'\xff')
    if sync_index == -1:
        return data
    data = bytearray(data)
    d = bytearray()
    while sync_index != -1:
        d += data[:sync_index]
        if data[sync_index + 1:sync_index + 3] == b'\x00\x00':
            d += b'\xff\x00'
            data = data[sync_index + 3:]
        elif data[sync_index + 1:sync_index + 2] == b'\x00':
            d += b'\xff'
            data = data[sync_index + 2:]
        else:
            d += b'\xff'
            data = data[sync_index + 1:]
        sync_index = data.find(b'\xff')
    d += data
    return bytes(d)


@classmethod
def register(cls, name, encode, decode):
    """Add a codec to the registry.

        Registers a codec with the given `name` (a string) to be used with the
        given `encode` and `decode` functions, which take a `bytes` object and
        return another one.  An existing codec is replaced.

        >>> import binascii
        >>> CodecReg.register('uu', binascii.b2a_uu, binascii.a2b_uu)
        >>> CodecReg.get_decoder('uu') is binascii.a2b_uu
        True
        >>> CodecReg.reset()
        >>> 'uu' in CodecReg
        False
        """
    cls._codecs[name] = cls._codec(encode, decode)


def normalize_pep440(**kwd):
    """ Normalize the version.

        >>> normalize_pep440(**parse_pep440('1.2.3.4.rc5.post.dev'))
        '1.2.3.4rc5'
    """
    normalized = '.'.join(map(str, kwd['release']))
    if 'pre_release' in kwd:
        normalized += '%s%s' % kwd['pre_release']
    if 'post_release' in kwd:
        normalized += '.post' + str(kwd['post_release'])
    if 'dev_release' in kwd:
        normalized += '.dev' + str(kwd['dev_release'])
    if 'epoch' in kwd:
        normalized = '{}!{}'.format(kwd['epoch'], normalized)
    return normalized


def _SplitHalves(full_pattern):
    """Attempt splits at halves."""
    splits = []
    n = len(full_pattern)
    if n % 2 == 0:
        m = n // 2
        splits.append([full_pattern[:m], full_pattern[m:]])
    else:
        for m in [(n - 1) // 2, (n + 1) // 2]:
            splits.append([full_pattern[:m], full_pattern[m:]])
    return splits


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

        :param SharedFolderAccessError val:
        :rtype: TransferFolderError
        """
    return cls('access_error', val)


def first_para(input, **kwargs):
    """get only ttext before a \\n (i.e. the fist paragraph)"""
    return input.split('\n')[0]


def readCommaList(fileList):
    """ Return a list of the files with the commas removed. """
    names = fileList.split(',')
    fileList = []
    for item in names:
        fileList.append(item)
    return fileList


def _compute_element_numbers(elements):
    """Build map from elements to element numbers."""
    element_numbers = {}
    for i, element in enumerate(elements):
        element_numbers[element] = i
    return element_numbers


def coerce_put_post(request):
    """
    Django doesn't particularly understand REST.
    In case we send data over PUT, Django won't
    actually look at the data and load it. We need
    to twist its arm here.

    The try/except abominiation here is due to a bug
    in mod_python. This should fix it.
    """
    if request.method == 'PUT':
        if hasattr(request, '_post'):
            del request._post
            del request._files
        try:
            request.method = 'POST'
            request._load_post_and_files()
            request.method = 'PUT'
        except AttributeError:
            request.META['REQUEST_METHOD'] = 'POST'
            request._load_post_and_files()
            request.META['REQUEST_METHOD'] = 'PUT'
        request.PUT = request.POST


def ts_truncate_seconds(timestamp):
    """
    Set seconds to zero in a timestamp.

    :param ts: Timestamp in seconds.
    :type ts: int

    :return: Timestamp in seconds, but without counting them (ie: DD-MM-YY HH:MM:00)
    :rtype: int
    """
    return timestamp - timestamp % 60


def _bool_encode(d):
    """
    Converts boolean values to lowercase strings

    """
    for k, v in d.items():
        if isinstance(v, bool):
            d[k] = str(v).lower()
    return d


def mob_masetti_phos(N):
    """Return the mobility of carriers (cm²/Vs) in phosphorus doped silicon accoording to the model of Masetti1983.
    Where N is the doping (cm-3)
    http://dx.doi.org/10.1109%2FT-ED.1983.21207"""
    μmax = 1414
    μmin = 68.5
    u1 = 56.1
    Cr = 9.2e+16
    Cs = 3.41e+20
    a = 0.711
    b = 1.98
    return μmin + (μmax - μmin) / (1 + (N / Cr) ** a) - u1 / (1 + (Cs / N) ** b
        )


def read_varlen_number(stream):
    """Read while the most significant bit is set, then put the 7 least
    significant bits of all read bytes together to create a number.

    """
    value = 0
    while True:
        byte = ord(stream.read(1))
        if not byte & 128:
            return value << 7 | byte
        value = value << 7 | byte & 127


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

        :param SharedContentViewType val:
        :rtype: EventType
        """
    return cls('shared_content_view', val)


def formatnextmessage(options, content):
    """Format the next message"""
    foundprefix = False
    nextmessage = ''
    language = content[0:2]
    for parameter in options['prefix']:
        if parameter.endswith('_prefix'):
            if parameter.startswith(language):
                foundprefix = True
                nextmessage = ' '.join([options['prefix'][parameter],
                    content[3:]])
    if not foundprefix:
        nextmessage = ' '.join([options['prefix']['prefix'], content[0:]])
    nextmessage = nextmessage.replace('\\n', '\n')
    return nextmessage, language


def yield_id(tree):
    """
    Function making it possible to yield id of tree's root

    Input:
    ------

    The tree structure of the junction tree

    Output:
    -------

    Clique ID of tree root

    """
    yield tree[0]


def cite():
    """Print the reference"""
    cite_data = """
===========  MLA ===========
Bosch, J., Marxer, R., Gomez, E., "Evaluation and Combination of
Pitch Estimation Methods for Melody Extraction in Symphonic
Classical Music", Journal of New Music Research (2016)

========== Bibtex ==========
@article{bosch2016evaluation,
    title={Evaluation and combination of pitch estimation methods for melody extraction in symphonic classical music},
    author={Bosch, Juan J and Marxer, Ricard and G{'o}mez, Emilia},
    journal={Journal of New Music Research},
    volume={45},
    number={2},
    pages={101--117},
    year={2016},
    publisher={Taylor \\& Francis}
"""
    print(cite_data)


@classmethod
def search(cls, q=None, sort=None, page=1, size=1000, sandbox=False,
    all_versions=False, max_pages=10):
    """Search public records

        It is possible to filter the results use the optional parameters.  Note that the web interface
        can sometimes be used to find search parameters by looking in the `search-hidden-params`
        parameter of the `invenio-search` tag.

        Example queries
        ===============
        'title:"SXS:BBH:0003"'  # Finds titles with given string; use quotes for robustness
        'communities:sxs'  # Records in the 'sxs' Zenodo community
        'provisional_communities:sxs'  # Records awaiting approval by the community curator
        'owners: 38418'  # Find records by id number of owner

        Optional parameters
        ===================
        q: string
            Search query, using Elasticsearch query string syntax.  See
            https://help.zenodo.org/guides/search/ for details.
        sort: string
            Sort order ('bestmatch' or 'mostrecent').  Prefix with minus to change from ascending to
            descending (e.g., '-mostrecent').
        page: int
            Page number for pagination
        size: int
            Number of results to return per page.  Note that Zenodo (as of this writing) seems to
            place a hard limit of 9999 responses.  Anything more will result in an error.  Use
            multiple pages to get more results.
        sandbox: bool [defaults to False]
            If True use sandbox.zenodo.org instead of the standard site.
        all_versions: bool [defaults to False]
            If True return all records, including older versions of published records.
        max_pages: int [defaults to 10]
            If the query returns a number of records equal to `size`, it is evidently incomplete.
            This function will attempt to retrieve successive pages until the number of records is
            less than `size`.  If the query is still incomplete after this many pages, just return
            what we've got.

        """
    import requests
    from . import url_sandbox, url_standard
    if sandbox:
        base_url = url_sandbox
    else:
        base_url = url_standard
    url = base_url + 'api/records/'
    params = {}
    if q is not None:
        params['q'] = q
    if sort is not None:
        params['sort'] = sort
    params['page'] = page
    params['size'] = size
    if all_versions:
        params['all_versions'] = ''
    r = requests.get(url, params=params, headers={'Accept': 'application/json'}
        )
    if r.status_code != 200:
        print('An unknown error occurred when trying to access {0}.'.format
            (url))
        print('The search parameters were "{0}"'.format(params))
        try:
            print(r.json())
        except:
            pass
        r.raise_for_status()
        raise RuntimeError()
    json = r.json()
    if len(json) == size:
        page += 1
        if page > max_pages:
            print(
                'Search is not yet complete after {0} pages; returning with what we have.'
                .format(max_pages))
            return r.json()
        return json + cls.search(q=q, sort=sort, page=page, size=size,
            sandbox=sandbox, all_versions=all_versions, max_pages=max_pages)
    return json


def get_readonly_uri():
    """Return the URI string that can be used by others to get read-only
        access to this node. The result is a read-only URI, regardless of
        whether this node is read-only or read-write.

        If you have merely read-only access to this node, get_readonly_uri()
        will return the same thing as get_uri().
        """


def freeze(duration=None):
    """freeze context with an endable freeze, and return token.
        """


def cull(data, index, min=None, max=None):
    """Sieve an emcee clouds by excluding walkers with search variable 'index'
    smaller than 'min' or larger than 'max'."""
    ret = data
    if min is not None:
        ret = ret[(ret[:, (index)] > min), :]
    if max is not None:
        ret = ret[(ret[:, (index)] < max), :]
    return ret


def get_object_from_filter(obj, components):
    """Gets the object whose attributes are actually being queried, which may be
    a different object if there is a chain.

    :param obj: the intial object.
    :param list components: the components of the original key.
    :returns: the relevant object"""
    components = components[:]
    while len(components) > 2:
        obj = getattr(obj, components.pop(0))
    if len(components) == 2:
        if components[-1] != 'regex':
            if not hasattr(obj, f'__{components[-1]}__'):
                obj = getattr(obj, components[0])
    return obj


@classmethod
def create(cls, model, name, **kwargs):
    """Instantiate this sub-graph from the generalized representation from `baseline.w2v`

        :param name: The name of the embeddings
        :param model: The `baseline.w2v` model
        :param kwargs:
        :return:
        """
    kwargs.pop('dsz', None)
    return cls(name=name, vsz=model.vsz, dsz=model.dsz, weights=model.
        weights, **kwargs)


def search_device(requirement, devices):
    """
    Returns a sufficient device or None

    :param requirement: The requirement to fulfill
    :type requirement: GPURequirement
    :param devices: The list of available devices
    :type devices: List[GPUDevice]
    :return: A device from the list
    """
    for device in devices:
        if requirement.is_sufficient(device):
            return device
    return None


@classmethod
def deserialize(cls, b: bytes):
    """Deserializes bytes to a packet."""
    packet = cls()
    pos = 0
    for name in packet.serializable_fields:
        field = getattr(type(packet), name)
        if field.is_dynamic_length:
            bslice = b[pos:pos + 4]
            pos = pos + 4
            field_len = int.from_bytes(bslice, 'big')
        else:
            field_len = len(field.serialize(getattr(packet, name)))
        bslice = b[pos:pos + field_len]
        pos = pos + field_len
        setattr(packet, name, field.deserialize(bslice))
    return packet


@classmethod
def response_payload(cls, result, request_id):
    """JSON v1 response payload."""
    return {'result': result, 'error': None, 'id': request_id}


def release_local(local):
    """Releases the contents of the local for the current context.
    This makes it possible to use locals without a manager.

    Example::

        >>> loc = Local()
        >>> loc.foo = 42
        >>> release_local(loc)
        >>> hasattr(loc, 'foo')
        False

    With this function one can release :class:`Local` objects as well
    as :class:`StackLocal` objects.  However it is not possible to
    release data held by proxies that way, one always has to retain
    a reference to the underlying local object in order to be able
    to release it.

    .. versionadded:: 0.6.1
    """
    local.__release_local__()


def n_m_to_ansi_j(n, m):
    """Convert (n,m) two term index to ANSI single term index."""
    return int((n * (n + 2) + m) / 2)


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


@staticmethod
def warning(message):
    """Log a warning level log message."""
    print('WARNING: ' + message)


def job_task_run(job, method, **kwargs):
    """
	Runs an arbitrary method of job; used by job_task.
	"""
    return getattr(job, method)(**kwargs)


def copy_storage(sourcestore, deststore):
    """Copies the files from the source storage object to the destination
    storage object using ``shutil.copyfileobj``.
    """
    from shutil import copyfileobj
    for name in sourcestore.list():
        with sourcestore.open_file(name) as source:
            with deststore.create_file(name) as dest:
                copyfileobj(source, dest)


def forward(apps, schema_editor):
    """Empty forward method."""
    pass


@classmethod
def has_archiving(cls):
    """Returns whether it supports archiving items on the fetch process.

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


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 giveMeasureTypeUnits(measureName, measureType=None):
    """ Given a measure name, returns its units and its type.

    :param measureName: Name of the measure
    :type measureName: str
    :param measureType: Type of the measure (optional)
    :type measureType: str
    :return: A 2-tuple containing the type of the measure and the units
    :rtype: str,str
    """
    if measureType is None:
        if measureName == 'ER' or measureName == 'DIFF':
            measureType = 'SV'
        else:
            measureType = measureName
    if measureType == 'MF':
        units = 'nT'
    elif measureType == 'SV':
        units = 'nT/yr'
    elif measureType == 'U':
        units = 'km/yr'
    elif measureType == 'DIVHU':
        units = '/yr'
    else:
        print(
            'Measure name not recognized for %s in giveMeasureTypeUnits. Setting units to nT.'
            , measureName)
        units = 'nT'
    return measureType, units


def extract_meta(response=None):
    """Extract meta object from response if possible."""
    if hasattr(response, 'meta') and response.meta:
        return response.meta
    if hasattr(response, 'request') and hasattr(response.request, 'meta'):
        return response.request.meta or {}
    return {}


def get_all_lines(file):
    """
    Reads a file returning all it's lines in a array of lines format.
    """
    line = file.readline()
    lines = []
    while line:
        lines.append(line)
        line = file.readline()
    return lines


def check_pip_failed(error_str):
    """Check if the error output contains Pip failed message"""
    error_lines = error_str.split('\n')
    for line in error_lines:
        if 'Pip failed' in line:
            return True
    return False


def items():
    """-> a sequence of tuples (oid, value) for cached objects.

        o Only includes items in 'data' (no p-classes).
        """


@staticmethod
def supports_dry_runs():
    """ The Trello plugin supports dry runs.

        Returns:
            bool: True
        """
    return True


def datetime_to_dateint(datetime_obj):
    """Converts the given datetime object to the corresponding dateint.

    Arguments
    ---------
    datetime_obj : datetime.datetime
        A datetime object decipting a specific point in time.

    Returns
    -------
    int
        An integer represeting the day, month and year of the given point in
        time. For example, 3:32 AM on December 3rd 2015 will be converted to
        the integer 20151203.
    """
    return (datetime_obj.year * 10000 + datetime_obj.month * 100 +
        datetime_obj.day)


def minimal_pairs(one, other):
    """ Find pairs of values in one and other with minimal distance.
    Assumes one and other are sorted in the same sort sequence.

    Parameters
    ----------
    one, other : sequence
        Sequence of scalars to find pairs from.

    Returns
    -------
    `tuple`
         Pairs of values in `one` and `other` with minimal distance
    """
    lbestdiff = bestdiff = bestj = besti = None
    for i, freq in enumerate(one):
        lbestj = bestj
        bestdiff, bestj = None, None
        for j, o_freq in enumerate(other[lbestj:]):
            j = lbestj + j if lbestj else j
            diff = abs(freq - o_freq)
            if bestj is not None and diff > bestdiff:
                break
            if bestj is None or bestdiff > diff:
                bestj = j
                bestdiff = diff
        if lbestj is not None and lbestj != bestj:
            yield besti, lbestj, lbestdiff
            besti = i
            lbestdiff = bestdiff
        elif lbestdiff is None or bestdiff < lbestdiff:
            besti = i
            lbestdiff = bestdiff
    yield besti, bestj, lbestdiff


@staticmethod
def user_input(text):
    """Wrap input() making testing support of py2 and py3 easier."""
    return input(text).strip()


@staticmethod
def query_group(q_object, args):
    """
        Subselect to filter data nodes by their group.

        :param q_object: a query object
        :param args: a namespace with parsed command line parameters.
        """
    from django.db.models import Q
    if args.group_name is not None:
        q_object.add(Q(dbgroups__name__in=args.group_name), Q.AND)
    if args.group_pk is not None:
        q_object.add(Q(dbgroups__pk__in=args.group_pk), Q.AND)


def are_column_aligned(token_a, token_b):
    """
  Return true if both tokens are on the same column.
  """
    return token_a.begin.col == token_b.begin.col


def _shortname(some_string, maxlen=20):
    """Shorten a string given a maximum length.

    Longer strings will be shortened and the rest replaced by ...

    Parameters
    ----------
    some_string : string
        Input string to shorten
    maxlen : int, default=20

    Returns
    -------
    return_string : string
        Output string of size ``min(len(some_string), maxlen)``.
    """
    some_string = str(some_string)
    if len(some_string) > maxlen:
        return some_string[:maxlen - 3] + '...'
    else:
        return some_string


def score_transcripts(user_transcript: list, other_transcript: list) ->float:
    """Score transcripts based on exons values

    The score moves between 0 and 1
    The score is 1 when they match perfectly, and 0 when they do not match at all.

    :param user_transcript:
    :type user_transcript: list
    :param other_transcript:
    :type other_transcript: list
    :return: float
    """
    matches = 0
    for user_exon in user_transcript:
        for db_exon in other_transcript:
            if user_exon['real_start'] == db_exon['real_start'] and user_exon[
                'real_end'] == db_exon['real_end']:
                matches += 1
    score = matches / len(user_transcript)
    return score


def allowCheckin(content):
    """
        denotes whether a checkin operation can be performed on the content.
        """


def error(e):
    """
    get errorno from Exception
    """
    if hasattr(e, 'errno'):
        return e.errno
    elif e.args:
        return e.args[0]
    else:
        return None


def make_image_url(reg, path, name='', tag='', digest='', empty_name_ok=False):
    """Construct a string from (path, name, tag)

	Essentially the opposite of parse_image_url()"""
    if reg:
        path = reg + '/' + path
        if path.endswith('/'):
            path = path[:-1]
    if name:
        if tag:
            if digest:
                image = name + ':' + tag + '@' + digest
            else:
                image = name + ':' + tag
        elif digest:
            image = name + '@' + digest
        else:
            image = name
    elif not empty_name_ok and (path or tag or digest):
        raise ValueError('Invalid image url: missing image name')
    else:
        image = ''
    if path:
        return path + '/' + image
    else:
        return image


def set_minimum(min_freq=None, min_time=None, min_off=None, min_res=None,
    min_angle=None):
    """
    Set minimum values of parameters.

    The given parameters are set to its minimum value if they are smaller.

    .. note::

        set_minimum and get_minimum are derived after set_printoptions and
        get_printoptions from arrayprint.py in numpy.

    Parameters
    ----------
    min_freq : float, optional
        Minimum frequency [Hz] (default 1e-20 Hz).
    min_time : float, optional
        Minimum time [s] (default 1e-20 s).
    min_off : float, optional
        Minimum offset [m] (default 1e-3 m).
        Also used to round src- & rec-coordinates.
    min_res : float, optional
        Minimum horizontal and vertical resistivity [Ohm.m] (default 1e-20).
    min_angle : float, optional
        Minimum angle [-] (default 1e-10).

    """
    global _min_freq, _min_time, _min_off, _min_res, _min_angle
    if min_freq is not None:
        _min_freq = min_freq
    if min_time is not None:
        _min_time = min_time
    if min_off is not None:
        _min_off = min_off
    if min_res is not None:
        _min_res = min_res
    if min_angle is not None:
        _min_angle = min_angle


def describe_cases(caseIdList=None, displayId=None, afterTime=None,
    beforeTime=None, includeResolvedCases=None, nextToken=None, maxResults=
    None, language=None, includeCommunications=None):
    """
    Returns a list of cases that you specify by passing one or more case IDs. In addition, you can filter the cases by date by setting values for the afterTime and beforeTime request parameters. You can set values for the includeResolvedCases and includeCommunications request parameters to control how much information is returned.
    Case data is available for 12 months after creation. If a case was created more than 12 months ago, a request for data might cause an error.
    The response returns the following in JSON format:
    See also: AWS API Documentation

    :example: response = client.describe_cases(
        caseIdList=[
            'string',
        ],
        displayId='string',
        afterTime='string',
        beforeTime='string',
        includeResolvedCases=True|False,
        nextToken='string',
        maxResults=123,
        language='string',
        includeCommunications=True|False
    )

    :type caseIdList: list
    :param caseIdList: A list of ID numbers of the support cases you want returned. The maximum number of cases is 100.
            (string) --

    :type displayId: string
    :param displayId: The ID displayed for a case in the AWS Support Center user interface.

    :type afterTime: string
    :param afterTime: The start date for a filtered date search on support case communications. Case communications are available for 12 months after creation.

    :type beforeTime: string
    :param beforeTime: The end date for a filtered date search on support case communications. Case communications are available for 12 months after creation.

    :type includeResolvedCases: boolean
    :param includeResolvedCases: Specifies whether resolved support cases should be included in the DescribeCases results. The default is false .

    :type nextToken: string
    :param nextToken: A resumption point for pagination.

    :type maxResults: integer
    :param maxResults: The maximum number of results to return before paginating.

    :type language: string
    :param language: The ISO 639-1 code for the language in which AWS provides support. AWS Support currently supports English ('en') and Japanese ('ja'). Language parameters must be passed explicitly for operations that take them.

    :type includeCommunications: boolean
    :param includeCommunications: Specifies whether communications should be included in the DescribeCases results. The default is true .

    :rtype: dict
    :return: {
        'cases': [
            {
                'caseId': 'string',
                'displayId': 'string',
                'subject': 'string',
                'status': 'string',
                'serviceCode': 'string',
                'categoryCode': 'string',
                'severityCode': 'string',
                'submittedBy': 'string',
                'timeCreated': 'string',
                'recentCommunications': {
                    'communications': [
                        {
                            'caseId': 'string',
                            'body': 'string',
                            'submittedBy': 'string',
                            'timeCreated': 'string',
                            'attachmentSet': [
                                {
                                    'attachmentId': 'string',
                                    'fileName': 'string'
                                },
                            ]
                        },
                    ],
                    'nextToken': 'string'
                },
                'ccEmailAddresses': [
                    'string',
                ],
                'language': 'string'
            },
        ],
        'nextToken': 'string'
    }

    :returns:
    caseIdList (list) -- A list of ID numbers of the support cases you want returned. The maximum number of cases is 100.

    (string) --

    displayId (string) -- The ID displayed for a case in the AWS Support Center user interface.
    afterTime (string) -- The start date for a filtered date search on support case communications. Case communications are available for 12 months after creation.
    beforeTime (string) -- The end date for a filtered date search on support case communications. Case communications are available for 12 months after creation.
    includeResolvedCases (boolean) -- Specifies whether resolved support cases should be included in the  DescribeCases results. The default is false .
    nextToken (string) -- A resumption point for pagination.
    maxResults (integer) -- The maximum number of results to return before paginating.
    language (string) -- The ISO 639-1 code for the language in which AWS provides support. AWS Support currently supports English ("en") and Japanese ("ja"). Language parameters must be passed explicitly for operations that take them.
    includeCommunications (boolean) -- Specifies whether communications should be included in the  DescribeCases results. The default is true .

    """
    pass


def format_sharded_filename(base_name: str, shards: int, index: int):
    """
    Formats the filename for a shard in sharded output.

    :param base_name:   The base filename to use.
    :param shards:      The number of shards being output, total.
    :param index:       The index of the current shard [0:shards).
    :return:            The formatted filename.
    """
    return f'{base_name}-{index:05}-of-{shards:05}'


def _interface_resolve_type(result, info, return_type):
    """Resolves the correct type for an interface"""
    return result.__class__.graphql_type


def stroke_subdivide(number_cuts: int=1, factor: float=0.0, repeat: int=1,
    only_selected: bool=True, smooth_position: bool=True, smooth_thickness:
    bool=True, smooth_strength: bool=False, smooth_uv: bool=False):
    """Subdivide between continuous selected points of the stroke adding a point half way between them

    :param number_cuts: Number of Cuts
    :type number_cuts: int
    :param factor: Smooth
    :type factor: float
    :param repeat: Repeat
    :type repeat: int
    :param only_selected: Selected Points, Smooth only selected points in the stroke
    :type only_selected: bool
    :param smooth_position: Position
    :type smooth_position: bool
    :param smooth_thickness: Thickness
    :type smooth_thickness: bool
    :param smooth_strength: Strength
    :type smooth_strength: bool
    :param smooth_uv: UV
    :type smooth_uv: bool
    """
    pass


def get_version():
    """! Get mbed-ls Python module version string """
    import pkg_resources
    return pkg_resources.require('mbed-ls')[0].version


def get_signal(obj, signalname):
    """Return signal from object and signal name."""
    if '(' not in signalname:
        return getattr(obj, signalname)
    name, dtype = signalname.strip(')').split('(')
    dtype = tuple(dtype.split(','))
    return getattr(obj, name)[dtype]


def countDict(arr):
    """count array to dict
  """
    data = {}
    for d in arr:
        if d not in data:
            data[d] = 0
        data[d] += 1
    return data


def fileno():
    """
        @raise: If the descriptor no longer has a valid file descriptor
            number associated with it.

        @return: The platform-specified representation of a file descriptor
            number.  Or C{-1} if the descriptor no longer has a valid file
            descriptor number associated with it.  As long as the descriptor
            is valid, calls to this method on a particular instance must
            return the same value.
        """


def heads(start=None):
    """Obtain list of nodes that are DAG heads."""


def hex_decode(data):
    """
	Takes an array of number and turns them into a string of hex for printing.

	in: data - array of numbers [1,2,33,42,234]
	out: str - '0x1 0x02 0x21 0x2a 0xea'
	"""
    return ''.join(map('0x{:02X} '.format, data))


def kwargs_extract(default, **kwargs):
    """
    like kwargs_update but extracts keys of default from kwargs

    Returns:
    k -- dictionary based on default update for kwargs
    l -- kwargs without keys defined in default
    """
    k = default.copy()
    l = {}
    for key, val in kwargs.items():
        if key in k.keys():
            k[key] = val
        else:
            l[key] = val
    return k, l


def uniquify(value, seen_values):
    """ Adds value to seen_values set and ensures it is unique """
    id = 1
    new_value = value
    while new_value in seen_values:
        new_value = '%s%s' % (value, id)
        id += 1
    seen_values.add(new_value)
    return new_value


def asymptotic_decay(learning_rate, t, max_iter):
    """Decay function of the learning process.
    Parameters
    ----------
    learning_rate : float
        current learning rate.

    t : int
        current iteration.

    max_iter : int
        maximum number of iterations for the training.
    """
    return learning_rate / (1 + t / (max_iter / 2))


def interval_overlap_length(i1, i2):
    """Compute the length of overlap of two intervals.

    Parameters
    ----------
    i1, i2 : pairs of two floats
        The two intervals.

    Returns
    -------
    l : float
        The length of the overlap between the two intervals.

    """
    a, b = i1
    c, d = i2
    if a < c:
        if b < c:
            return 0.0
        elif b < d:
            return b - c
        else:
            return d - c
    elif a < d:
        if b < d:
            return b - a
        else:
            return d - a
    else:
        return 0


@classmethod
def supported(cls, conn):
    """Return whether keyboard interactive authentication is supported"""
    return conn.kbdint_auth_supported()


def order_result():
    """
    Get a specific order
    """
    raise NotImplemented


def p_language_map(t):
    """language_map : LANGUAGE_MAP START_BLOCK language_mappings END_BLOCK"""
    from audiotools.toc import CDTextLanguageMap
    t[0] = CDTextLanguageMap(t[3])


def json_to_yaml(content):
    """
    TODO: convert json to yaml
    """
    return content


def cycle_slice(sliceable, start, end):
    """Given a list, return right hand cycle direction slice from start to end.

    Example::

        >>> array = [0, 1, 2, 3]
        >>> cycle_slice(array, 1, 3) # from array[1] to array[3]
        [1, 2]

        >>> cycle_slice(array, 3, 1) # from array[3] to array[1]
        [3, 0]

    **中文文档**

    """
    if type(sliceable) != list:
        sliceable = list(sliceable)
    length = len(sliceable)
    if length == 0:
        raise ValueError('sliceable cannot be empty!')
    start = start % length
    end = end % length
    if end > start:
        return sliceable[start:end]
    elif end <= start:
        return sliceable[start:] + sliceable[:end]


def free2tot(TSO4, KSO4):
    """Free to Total pH scale conversion factor."""
    return 1.0 + TSO4 / KSO4


def psi_Ca_HCO3_HSO4_HMW84(T, P):
    """c-a-a': calcium bicarbonate bisulfate [HMW84]."""
    psi = 0.0
    valid = T == 298.15
    return psi, valid


def _update_nodes(model, starting_id_dict, nid, nid_map):
    """updates the nodes"""
    if 'nid' in starting_id_dict and nid is not None:
        for nid, node in sorted(model.nodes.items()):
            nid_new = nid_map[nid]
            node.nid = nid_new


def check_valid_input(input_value):
    """Checks if an input value corresponds to a valid value - i.e. not None, "", "None",..."""
    if input_value is None or input_value == '' or input_value == 'None':
        valid = False
    else:
        valid = True
    return valid


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


def _is_epub(file_bytes: bytes) ->bool:
    """
	Decide if a file is an epub file.
	From https://github.com/h2non/filetype.py (MIT license)
	"""
    return len(file_bytes) > 57 and file_bytes[0] == 80 and file_bytes[1
        ] == 75 and file_bytes[2] == 3 and file_bytes[3] == 4 and file_bytes[30
        ] == 109 and file_bytes[31] == 105 and file_bytes[32
        ] == 109 and file_bytes[33] == 101 and file_bytes[34
        ] == 116 and file_bytes[35] == 121 and file_bytes[36
        ] == 112 and file_bytes[37] == 101 and file_bytes[38
        ] == 97 and file_bytes[39] == 112 and file_bytes[40
        ] == 112 and file_bytes[41] == 108 and file_bytes[42
        ] == 105 and file_bytes[43] == 99 and file_bytes[44
        ] == 97 and file_bytes[45] == 116 and file_bytes[46
        ] == 105 and file_bytes[47] == 111 and file_bytes[48
        ] == 110 and file_bytes[49] == 47 and file_bytes[50
        ] == 101 and file_bytes[51] == 112 and file_bytes[52
        ] == 117 and file_bytes[53] == 98 and file_bytes[54
        ] == 43 and file_bytes[55] == 122 and file_bytes[56
        ] == 105 and file_bytes[57] == 112


def add_keys(apps, schema_editor):
    """
    We can't import the Post model directly as it may be a newer
    version than this migration expects. We use the historical version.
    """
    Setting = apps.get_model('settings', 'Setting')
    key = ''
    try:
        key = 'COURSE_IGNORE_IN_LIST_IDS'
        Setting.objects.get(key=key)
    except Exception:
        Setting.objects.create(title='دوره هایی که در لیست نمی آیند', key=
            key, value='', value_type='s', is_show=False,
            is_variable_in_home=True)


def serial_escape(value):
    """Escape string values that are elements of a list, for serialization."""
    return value.replace('\\', '\\\\').replace(' ', '\\ ')


def _get_reason(cluster_or_step):
    """Get state change reason message."""
    return cluster_or_step['Status']['StateChangeReason'].get('Message', '')


def get_size():
    """ Return the size in bytes of the data in the blob associated with
        the file"""


def mse_to_roll(arr, Exp, ind):
    """Mean Squared Error used in the rolling function
    """
    temp = arr.value_counts(normalize=True).sort_index()
    if len(temp) < len(Exp):
        temp = temp.reindex(ind).fillna(0)
    return ((temp - Exp) ** 2).mean()


def binary_reduce(reducer, binary_op, graph, lhs, rhs, lhs_data, rhs_data,
    out_size, lhs_map, rhs_map, out_map):
    """Perform binary operation between given data and reduce based on graph
    structure.

    Parameters
    ----------
    reducer : str
        Type of reduction: 'sum', 'max', 'min', 'mean', 'prod', 'none' (no
        reduction)
    binary_op : str
        Binary operation to perform, can be 'add', 'mul', 'sub', 'div'
    graph : GraphIndex
        The graph
    lhs : int
        The lhs target (src, dst, edge)
    rhs : int
        The rhs target (src, dst, edge)
    lhs_data : Tensor
        The lhs data
    rhs_data : Tensor
        The rhs data
    out_size : int
        Size of first dimension of output data
    lhs_map : tuple
        Two lhs id mapping arrays, one for forward pass, the other for backward
    rhs_map : tuple
        Two rhs id mapping arrays, one for forward pass, the other for backward
    out_map : tuple
        Two out id mapping arrays, one for forward pass, the other for backward

    Returns
    -------
    Tensor
        The result.
    """
    pass


def is_artist_id(item_id):
    """Validate if ID is in the format of a Google Music artist ID."""
    return len(item_id) == 27 and item_id.startswith('A')


def demical2clock(demicaltime):
    """
    Convert demical time view to Hours, Minutes and Seconds.

    Args:
        demicaltime (float): time to be converted.

    Returns:
        str: one string representation in hours, minutes format.

    """
    h = int(demicaltime)
    m = int((demicaltime - h) * 60)
    s = int(((demicaltime - h) * 60 - m) * 60)
    h = str(h)
    m = str(m)
    s = str(s)
    if len(h) == 1:
        h = '0' + h
    if len(m) == 1:
        m = '0' + m
    if len(s) == 1:
        s = '0' + s
    res = h + ':' + m + ':' + s
    return res


@classmethod
def parseConfigString(cls, configString):
    """Parse a config string and build a config dict from it.
		"""
    configDict = {}
    for config in configString.split(';'):
        idx = config.find('=')
        if idx <= 0:
            return None
        k = config[:idx]
        v = config[idx + 1:]
        configDict[k] = v
    return configDict


def add512bit(a, b):
    """ Add two 512 integers
    """
    a = bytearray(a)
    b = bytearray(b)
    cb = 0
    res = bytearray(64)
    for i in range(64):
        cb = a[i] + b[i] + (cb >> 8)
        res[i] = cb & 255
    return res


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 _on_message_simple(client, userdata, message):
    """Internal callback"""
    if userdata['msg_count'] == 0:
        return
    if message.retain and not userdata['retained']:
        return
    userdata['msg_count'] = userdata['msg_count'] - 1
    if userdata['messages'] is None and userdata['msg_count'] == 0:
        userdata['messages'] = message
        client.disconnect()
        return
    userdata['messages'].append(message)
    if userdata['msg_count'] == 0:
        client.disconnect()


def multiple_recombinations(ts):
    """
    Returns true if the specified tree sequence contains multiple recombinations.
    """
    for _, e_out, _ in ts.edge_diffs():
        if len(e_out) > 4:
            return True
    return False


def muvaluid(string):
    """
    Run suite fits: muvaluid returns True/False
    checks the syntax for string function
    corresponding to flag='l'. Meant for pars
    displaying large changes across the run suite,
    requiring different migrad start guesses.
    """
    try:
        value_times_list = string.split(',')
        last = value_times_list.pop()
        for value_times in value_times_list:
            value, times = value_times.split('*')
            dum, dum = float(value), int(times)
        dum = float(last)
        return True
    except:
        return False


def unfold(proc, *inits):
    """Like unfold1, but for n-in-(1+n)-out proc.

    The current state is unpacked to the argument list of ``proc``.
    It must return either ``(value, *newstates)``, or ``None`` to signify
    that the sequence ends.

    If your state is something simple such as one number, see ``unfold1``.

    Example::

        def fibo(a, b):
            return (a, b, a + b)

        assert tuple(take(10, unfold(fibo, 1, 1))) == \\
               (1, 1, 2, 3, 5, 8, 13, 21, 34, 55)
    """
    states = inits
    while True:
        result = proc(*states)
        if result is None:
            break
        value, *states = result
        yield value


def _dst_coords(src, like, dims_from_src, dims_from_like):
    """
    Gather destination coordinates
    """
    dst_da_coords = {}
    dst_shape = []
    like_coords = dict(like.coords)
    for dim in dims_from_src:
        try:
            like_coords.pop(dim)
        except KeyError:
            pass
        dst_da_coords[dim] = src[dim].values
        dst_shape.append(src[dim].size)
    for dim in dims_from_like:
        try:
            like_coords.pop(dim)
        except KeyError:
            pass
        dst_da_coords[dim] = like[dim].values
        dst_shape.append(like[dim].size)
    dst_da_coords.update(like_coords)
    return dst_da_coords, dst_shape


def p_dataline(p):
    """dataline : anytokens SEMICOLON"""


def is_lang_installed(lang):
    """Check to see if cis_interface can run models written in a programming
    language on the current machine.

    Args:
        lang (str): Programming language to check.

    Returns:
        bool: True if models in the provided language can be run on the current
            machine, False otherwise.

    """
    from cis_interface import schema, drivers
    s = schema.get_schema()
    drv = drivers.import_driver(s['model'].subtype2class[lang])
    return drv.is_installed()