Instruction:
Write a Python 3 function for
serving static files below a given point in the directory structure.

Response:
def media(self, request, module, path):
        """
        Serve static files below a given point in the directory structure.
        """
        if module == 'nexus':
            document_root = os.path.join(NEXUS_ROOT, 'media')
        else:
            document_root = self.get_module(module).media_root

        path = posixpath.normpath(urllib.unquote(path))
        path = path.lstrip('/')
        newpath = ''
        for part in path.split('/'):
            if not part:
                # Strip empty path components.
                continue
            drive, part = os.path.splitdrive(part)
            head, part = os.path.split(part)
            if part in (os.curdir, os.pardir):
                # Strip '.' and '..' in path.
                continue
            newpath = os.path.join(newpath, part).replace('\\', '/')
        if newpath and path != newpath:
            return HttpResponseRedirect(newpath)
        fullpath = os.path.join(document_root, newpath)
        if os.path.isdir(fullpath):
            raise Http404("Directory indexes are not allowed here.")
        if not os.path.exists(fullpath):
            raise Http404('"%s" does not exist' % fullpath)
        # Respect the If-Modified-Since header.
        statobj = os.stat(fullpath)
        mimetype = mimetypes.guess_type(fullpath)[0] or 'application/octet-stream'
        if not was_modified_since(request.META.get('HTTP_IF_MODIFIED_SINCE'),
                                  statobj[stat.ST_MTIME], statobj[stat.ST_SIZE]):
            return HttpResponseNotModified(content_type=mimetype)
        contents = open(fullpath, 'rb').read()
        response = HttpResponse(contents, content_type=mimetype)
        response["Last-Modified"] = http_date(statobj[stat.ST_MTIME])
        response["Content-Length"] = len(contents)
        return response


Instruction:
Create a Python 3 function for
logging out user and redirects them to Nexus home

Response:
def logout(self, request):
        "Logs out user and redirects them to Nexus home"
        from django.contrib.auth import logout

        logout(request)

        return HttpResponseRedirect(reverse('nexus:index', current_app=self.name))


Instruction:
Implement a function in Python 3 to
display the row of buttons for delete and save.

Response:
def submit_row(context):
    """
    Displays the row of buttons for delete and save.
    """
    opts = context['opts']
    change = context['change']
    is_popup = context['is_popup']
    save_as = context['save_as']
    return {
        'onclick_attrib': (opts.get_ordered_objects() and change
                            and 'onclick="submitOrderForm();"' or ''),
        'show_delete_link': (not is_popup and context['has_delete_permission']
                              and (change or context['show_delete'])),
        'show_save_as_new': not is_popup and change and save_as,
        'show_save_and_add_another': context['has_add_permission'] and
                            not is_popup and (not save_as or context['add']),
        'show_save_and_continue': not is_popup and context['has_change_permission'],
        'is_popup': is_popup,
        'show_save': True,
    }


Instruction:
Given the following Python 3 function, write the documentation
def autodiscover(site=None):
    # Bail out if autodiscover didn't finish loading from a previous call so
    # that we avoid running autodiscover again when the URLconf is loaded by
    # the exception handler to resolve the handler500 view.  This prevents an
    # admin.py module with errors from re-registering models and raising a
    # spurious AlreadyRegistered exception (see #8245).
    global LOADING
    if LOADING:
        return
    LOADING = True

    if site:
        orig_site = globals()['site']
        globals()['site'] = locals()['site']

    import imp
    from django.utils.importlib import import_module
    from django.conf import settings

    for app in settings.INSTALLED_APPS:
        # For each app, we need to look for an api.py inside that app's
        # package. We can't use os.path here -- recall that modules may be
        # imported different ways (think zip files) -- so we need to get
        # the app's __path__ and look for admin.py on that path.

        # Step 1: find out the app's __path__ Import errors here will (and
        # should) bubble up, but a missing __path__ (which is legal, but weird)
        # fails silently -- apps that do weird things with __path__ might
        # need to roll their own admin registration.
        try:
            app_path = import_module(app).__path__
        except (AttributeError, ImportError):
            continue

        # Step 2: use imp.find_module to find the app's admin.py. For some
        # reason imp.find_module raises ImportError if the app can't be found
        # but doesn't actually try to import the module. So skip this app if
        # its admin.py doesn't exist
        try:
            imp.find_module('nexus_modules', app_path)
        except ImportError:
            continue

        # Step 3: import the app's admin file. If this has errors we want them
        # to bubble up.
        import_module("%s.nexus_modules" % app)
    # # load builtins
    # from gargoyle.builtins import *

    if site:
        globals()['site'] = orig_site

    # autodiscover was successful, reset loading flag.
    LOADING = False

Response: Autodiscovers INSTALLED_APPS nexus. py modules and returns a nexus tree.


Instruction:
Explain what the following Python 3 code does
def handle_starttag(self, tagName, attributeList, isSelfClosing=False):
        '''
            Internal for parsing
        '''
        tagName = tagName.lower()
        inTag = self._inTag

        if isSelfClosing is False and tagName in IMPLICIT_SELF_CLOSING_TAGS:
            isSelfClosing = True

        newTag = AdvancedTag(tagName, attributeList, isSelfClosing, ownerDocument=self)
        if self.root is None:
            self.root = newTag
        elif len(inTag) > 0:
            inTag[-1].appendChild(newTag)
        else:
            raise MultipleRootNodeException()

        if isSelfClosing is False:
            inTag.append(newTag)

        return newTag

Response:
Internal for parsing
           .


Instruction:
How would you explain what the following Python 3 function does
def handle_endtag(self, tagName):
        '''
            Internal for parsing
        '''
        try:
            foundIt = False
            inTag = self._inTag
            for i in range(len(inTag)):
                if inTag[i].tagName == tagName:
                    foundIt = True
                    break

            if not foundIt:
                return
            # Handle closing tags which should have been closed but weren't
            while inTag[-1].tagName != tagName:
                inTag.pop()

            inTag.pop()
        except:
            pass

Response:
Internal for parsing
            Internal for parsing


Instruction:
Here you have a function in Python 3, explain what it does
def getRootNodes(self):
        '''
            getRootNodes - Gets all objects at the "root" (first level; no parent). Use this if you may have multiple roots (not children of <html>)
                Use this method to get objects, for example, in an AJAX request where <html> may not be your root.

                Note: If there are multiple root nodes (i.e. no <html> at the top), getRoot will return a special tag. This function automatically
                  handles that, and returns all root nodes.

                @return list<AdvancedTag> - A list of AdvancedTags which are at the root level of the tree.
        '''
        root = self.root
        if not root:
            return []
        if root.tagName == INVISIBLE_ROOT_TAG:
            return list(root.children)
        return [root]

Response: Get all objects at the root level of the tree.


Instruction:
Can you tell what is the following Python 3 function doing
def getAllNodes(self):
        '''
            getAllNodes - Get every element

            @return TagCollection<AdvancedTag>
        '''

        ret = TagCollection()

        for rootNode in self.getRootNodes():
            ret.append(rootNode)

            ret += rootNode.getAllChildNodes()

        return ret

Response: getAllNodes - Get every element of the tree


Instruction:
Here you have a function in Python 3, explain what it does
def getElementsByName(self, name, root='root'):
        '''
            getElementsByName - Searches and returns all elements with a specific name.

                @param name <str> - A string of the name attribute
                @param root <AdvancedTag/'root'> - Search starting at a specific node, if provided. if string 'root' [default], the root of the parsed tree will be used.
        '''
        (root, isFromRoot) = self._handleRootArg(root)

        elements = []

        if isFromRoot is True and root.name == name:
            elements.append(root)

        getElementsByName = self.getElementsByName
        for child in root.children:

            if child.getAttribute('name') == name:
                elements.append(child)

            elements += getElementsByName(name, child)

        return TagCollection(elements)

Response: getElementsByName - Searches and returns all elements with a specific name.


Instruction:
Make a summary of the following Python 3 code
def getElementById(self, _id, root='root'):
        '''
            getElementById - Searches and returns the first (should only be one) element with the given ID.

                @param id <str> - A string of the id attribute.
                @param root <AdvancedTag/'root'> - Search starting at a specific node, if provided. if string 'root' [default], the root of the parsed tree will be used.
        '''
        (root, isFromRoot) = self._handleRootArg(root)

        if isFromRoot is True and root.id == _id:
            return root

        getElementById = self.getElementById
        for child in root.children:

            if child.getAttribute('id') == _id:
                return child

            potential = getElementById(_id, child)
            if potential is not None:
                return potential

        return None

Response: Searches and returns the first element with the given ID.


Instruction:
Can you generate the documentation for the following Python 3 function
def getElementsByAttr(self, attrName, attrValue, root='root'):
        '''
            getElementsByAttr - Searches the full tree for elements with a given attribute name and value combination. This is always a full scan.

                @param attrName <lowercase str> - A lowercase attribute name
                @param attrValue <str> - Expected value of attribute
                @param root <AdvancedTag/'root'> - Search starting at a specific node, if provided. if string 'root', the root of the parsed tree will be used.
        '''
        (root, isFromRoot) = self._handleRootArg(root)

        elements = []

        if isFromRoot is True and root.getAttribute(attrName) == attrValue:
            elements.append(root)

        getElementsByAttr = self.getElementsByAttr
        for child in root.children:

            if child.getAttribute(attrName) == attrValue:
                elements.append(child)

            elements += getElementsByAttr(attrName, attrValue, child)

        return TagCollection(elements)

Response: getElementsByAttr - Searches the full tree for elements with a given attribute name and value combination. This is always a full scan.


Instruction:
Explain what the following Python 3 code does
def getElementsCustomFilter(self, filterFunc, root='root'):
        '''
            getElementsCustomFilter - Scan elements using a provided function

            @param filterFunc <function>(node) - A function that takes an AdvancedTag as an argument, and returns True if some arbitrary criteria is met

            @return - TagCollection of all matching elements
        '''
        (root, isFromRoot) = self._handleRootArg(root)

        elements = []

        if isFromRoot is True and filterFunc(root) is True:
            elements.append(root)

        getElementsCustomFilter = self.getElementsCustomFilter
        for child in root.children:

            if filterFunc(child) is True:
                elements.append(child)

            elements += getElementsCustomFilter(filterFunc, child)

        return TagCollection(elements)

Response: getElementsCustomFilter - Scan elements using a provided function


Instruction:
Can you tell what is the following Python 3 function doing
def contains(self, em):
        '''
            Checks if #em is found anywhere within this element tree

            @param em <AdvancedTag> - Tag of interest

            @return <bool> - If element #em is within this tree
        '''
        for rootNode in self.getRootNodes():
            if rootNode.contains(em):
                return True

        return False

Response: Checks if the given element is found anywhere within this tree.


Instruction:
Given the following Python 3 function, write the documentation
def containsUid(self, uid):
        '''
            Check if #uid is found anywhere within this element tree

            @param uid <uuid.UUID> - Uid

            @return <bool> - If #uid is found within this tree
        '''
        for rootNode in self.getRootNodes():
            if rootNode.containsUid(uid):
                return True

        return False

Response: Check if the uid is found anywhere within this element tree


Instruction:
Explain what the following Python 3 code does
def find(self, **kwargs):
        '''
            find - Perform a search of elements using attributes as keys and potential values as values

               (i.e.  parser.find(name='blah', tagname='span')  will return all elements in this document
                 with the name "blah" of the tag type "span" )

            Arguments are key = value, or key can equal a tuple/list of values to match ANY of those values.

            Append a key with __contains to test if some strs (or several possible strs) are within an element
            Append a key with __icontains to perform the same __contains op, but ignoring case

            Special keys:

               tagname    - The tag name of the element
               text       - The text within an element

            NOTE: Empty string means both "not set" and "no value" in this implementation.

            NOTE: If you installed the QueryableList module (i.e. ran setup.py without --no-deps) it is
              better to use the "filter"/"filterAnd" or "filterOr" methods, which are also available
              on all tags and tag collections (tag collections also have filterAllAnd and filterAllOr)

            @return TagCollection<AdvancedTag> - A list of tags that matched the filter criteria
        '''

        if not kwargs:
            return TagCollection()

        # Because of how closures work in python, need a function to generate these lambdas
        #  because the closure basically references "current key in iteration" and not
        #  "actual instance" of variable. Seems to me to be a bug... but whatever
        def _makeTagnameLambda(tagName):
            return lambda em : em.tagName == tagName

        def _makeAttributeLambda(_key, _value):
            return lambda em : em.getAttribute(_key, '') == _value

        def _makeTagnameInLambda(tagNames):
            return lambda em : em.tagName in tagNames

        def _makeAttributeInLambda(_key, _values):
            return lambda em : em.getAttribute(_key, '') in _values

        def _makeTextLambda(_value):
            return lambda em : em.text == _value

        def _makeTextInLambda(_values):
            return lambda em : em.text in _values

        def _makeAttributeContainsLambda(_key, _value, icontains=False):
            if icontains is False:
                return lambda em : _value in em.getAttribute(_key, '')
            else:
                _value = _value.lower()
                return lambda em : _value in em.getAttribute(_key, '').lower()

        def _makeTextContainsLambda(_value, icontains=False):
            if icontains is False:
                return lambda em : _value in em.text
            else:
                _value = _value.lower()
                return lambda em : _value in em.text.lower()

        def _makeAttributeContainsInLambda(_key, _values, icontains=False):
            if icontains:
                _values = tuple([x.lower() for x in _values])

            def _testFunc(em):
                attrValue = em.getAttribute(_key, '')
                if icontains:
                    attrValue = attrValue.lower()

                for value in _values:
                    if value in attrValue:
                        return True

                return False

            return _testFunc

        def _makeTextContainsInLambda(_values, icontains=False):
            if icontains:
                _values = tuple([x.lower() for x in _values])

            def _testFunc(em):
                text = em.text
                if icontains:
                    text = text.lower()

                for value in _values:
                    if value in text:
                        return True

                return False

            return _testFunc

        # This will hold all the functions we will chain for matching
        matchFunctions = []

        # Iterate over all the filter portions, and build a filter.
        for key, value in kwargs.items():
            key = key.lower()

            endsIContains = key.endswith('__icontains')
            endsContains = key.endswith('__contains')

            isValueList = isinstance(value, (list, tuple))

            thisFunc = None

            if endsIContains or endsContains:
                key = re.sub('__[i]{0,1}contains$', '', key)
                if key == 'tagname':
                    raise ValueError('tagname is not supported for contains')

                if isValueList:
                    if key == 'text':
                        thisFunc = _makeTextContainsInLambda(value, icontains=endsIContains)
                    else:
                        thisFunc = _makeAttributeContainsLambda(key, value, icontains=endsIContains)
                else:
                    if key == 'text':
                        thisFunc = _makeTextContainsLambda(value, icontains=endsIContains)
                    else:
                        thisFunc = _makeAttributeContainsLambda(key, value, icontains=endsIContains)

            else:
                # Not contains, straight up

                if isValueList:
                    if key == 'tagname':
                        thisFunc = _makeTagnameInLambda(value)
                    elif key == 'text':
                        thisFunc = _makeTextInLambda(value)
                    else:
                        thisFunc = _makeAttributeInLambda(key, value)
                else:
                    if key == 'tagname':
                        thisFunc = _makeTagnameLambda(value)
                    elif key == 'text':
                        thisFunc = _makeTextLambda(value)
                    else:
                        thisFunc = _makeAttributeLambda(key, value)

            matchFunctions.append( thisFunc )

        # The actual matching function - This will run through the assembled
        #  #matchFunctions list, testing the element against each match
        #  and returning all elements in a TagCollection that match this list.
        def doMatchFunc(em):
            for matchFunction in matchFunctions:
                if matchFunction(em) is False:
                    return False

            return True

        return self.getElementsCustomFilter(doMatchFunc)

Response: This method is used to find all tags in this document.


Instruction:
How would you code a function in Python 3 to
get the full HTML as contained within this tree.

Response:
def getHTML(self):
        '''
            getHTML - Get the full HTML as contained within this tree.

                If parsed from a document, this will contain the original whitespacing.

                @returns - <str> of html

                    @see getFormattedHTML

                    @see getMiniHTML
        '''
        root = self.getRoot()
        if root is None:
            raise ValueError('Did not parse anything. Use parseFile or parseStr')

        if self.doctype:
            doctypeStr = '<!%s>\n' %(self.doctype)
        else:
            doctypeStr = ''

        # 6.6.0: If we have a real root tag, print the outerHTML. If we have a fake root tag (for multiple root condition),
        #   then print the innerHTML (skipping the outer root tag). Otherwise, we will miss
        #   untagged text (between the multiple root nodes).
        rootNode = self.getRoot()
        if rootNode.tagName == INVISIBLE_ROOT_TAG:
            return doctypeStr + rootNode.innerHTML
        else:
            return doctypeStr + rootNode.outerHTML


Instruction:
How would you code a function in Python 3 to
get formatted and xhtml of this document replacing the original whitespace with a pretty - printed version of each level of indent.

Response:
def getFormattedHTML(self, indent='  '):
        '''
            getFormattedHTML - Get formatted and xhtml of this document, replacing the original whitespace
                with a pretty-printed version

            @param indent - space/tab/newline of each level of indent, or integer for how many spaces per level

            @return - <str> Formatted html

            @see getHTML - Get HTML with original whitespace

            @see getMiniHTML - Get HTML with only functional whitespace remaining
        '''
        from .Formatter import AdvancedHTMLFormatter
        html = self.getHTML()
        formatter = AdvancedHTMLFormatter(indent, None) # Do not double-encode
        formatter.feed(html)
        return formatter.getHTML()


Instruction:
How would you code a function in Python 3 to
get the HTML representation of this document without any pretty formatting and disregarding original whitespace beyond the functional.

Response:
def getMiniHTML(self):
        '''
            getMiniHTML - Gets the HTML representation of this document without any pretty formatting
                and disregarding original whitespace beyond the functional.

                @return <str> - HTML with only functional whitespace present
        '''
        from .Formatter import AdvancedHTMLMiniFormatter
        html = self.getHTML()
        formatter = AdvancedHTMLMiniFormatter(None) # Do not double-encode
        formatter.feed(html)
        return formatter.getHTML()


Instruction:
Write a Python 3 function that can
reset the internal state of the object.

Response:
def _reset(self):
        '''
            _reset - reset this object. Assigned to .reset after __init__ call.
        '''
        HTMLParser.reset(self)

        self.root = None
        self.doctype = None
        self._inTag = []


Instruction:
Here you have a function in Python 3, explain what it does
def feed(self, contents):
        '''
            feed - Feed contents. Use  parseStr or parseFile instead.

            @param contents - Contents
        '''
        contents = stripIEConditionals(contents)
        try:
            HTMLParser.feed(self, contents)
        except MultipleRootNodeException:
            self.reset()
            HTMLParser.feed(self, "%s%s" %(addStartTag(contents, INVISIBLE_ROOT_TAG_START), INVISIBLE_ROOT_TAG_END))

Response: Feed contents. Use parseStr or parseFile instead.


Instruction:
Can you tell what is the following Python 3 function doing
def parseFile(self, filename):
        '''
            parseFile - Parses a file and creates the DOM tree and indexes

                @param filename <str/file> - A string to a filename or a file object. If file object, it will not be closed, you must close.
        '''
        self.reset()

        if isinstance(filename, file):
            contents = filename.read()
        else:
            with codecs.open(filename, 'r', encoding=self.encoding) as f:
                contents = f.read()

        self.feed(contents)

Response: Parse a file and creates the DOM tree and indexes


Instruction:
How would you code a function in Python 3 to
parse a string and creates the DOM tree and indexes.

Response:
def parseStr(self, html):
        '''
            parseStr - Parses a string and creates the DOM tree and indexes.

                @param html <str> - valid HTML
        '''
        self.reset()

        if isinstance(html, bytes):
            self.feed(html.decode(self.encoding))
        else:
            self.feed(html)


Instruction:
Explain what the following Python 3 code does
def createElementFromHTML(cls, html, encoding='utf-8'):
        '''
            createElementFromHTML - Creates an element from a string of HTML.

                If this could create multiple root-level elements (children are okay),
                  you must use #createElementsFromHTML which returns a list of elements created.

            @param html <str> - Some html data

            @param encoding <str> - Encoding to use for document

            @raises MultipleRootNodeException - If given html would produce multiple root-level elements (use #createElementsFromHTML instead)

            @return AdvancedTag - A single AdvancedTag

            NOTE: If there is text outside the tag, they will be lost in this.
              Use createBlocksFromHTML instead if you need to retain both text and tags.

              Also, if you are just appending to an existing tag, use AdvancedTag.appendInnerHTML
        '''

        parser = cls(encoding=encoding)

        html = stripIEConditionals(html)
        try:
            HTMLParser.feed(parser, html)
        except MultipleRootNodeException:
            raise MultipleRootNodeException('Multiple nodes passed to createElementFromHTML method. Use #createElementsFromHTML instead to get a list of AdvancedTag elements.')

        rootNode = parser.getRoot()
        rootNode.remove()

        return rootNode

Response: Create an element from a string of HTML.


Instruction:
Can you tell what is the following Python 3 function doing
def createElementsFromHTML(cls, html, encoding='utf-8'):
        '''
            createElementsFromHTML - Creates elements from provided html, and returns a list of the root-level elements
                children of these root-level nodes are accessable via the usual means.

            @param html <str> - Some html data

            @param encoding <str> - Encoding to use for document

            @return list<AdvancedTag> - The root (top-level) tags from parsed html.

            NOTE: If there is text outside the tags, they will be lost in this.
              Use createBlocksFromHTML instead if you need to retain both text and tags.

              Also, if you are just appending to an existing tag, use AdvancedTag.appendInnerHTML
        '''
        # TODO: If text is present outside a tag, it will be lost.

        parser = cls(encoding=encoding)

        parser.parseStr(html)

        rootNode = parser.getRoot()

        rootNode.remove() # Detatch from temp document

        if isInvisibleRootTag(rootNode):
            return rootNode.children

        return [rootNode]

Response: Create elements from provided html and returns a list of the root - level elements that are accessable via the usual means.


Instruction:
Implement a function in Python 3 to
create blocks from HTML.

Response:
def createBlocksFromHTML(cls, html, encoding='utf-8'):
        '''
            createBlocksFromHTML - Returns the root level node (unless multiple nodes), and
                a list of "blocks" added (text and nodes).

            @return list< str/AdvancedTag > - List of blocks created. May be strings (text nodes) or AdvancedTag (tags)

            NOTE:
                Results may be checked by:

                    issubclass(block.__class__, AdvancedTag)

                If True, block is a tag, otherwise, it is a text node
        '''

        parser = cls(encoding=encoding)

        parser.parseStr(html)

        rootNode = parser.getRoot()

        rootNode.remove()

        return rootNode.blocks


Instruction:
How would you explain what the following Python 3 function does
def handle_starttag(self, tagName, attributeList, isSelfClosing=False):
        '''
            internal for parsing
        '''
        newTag = AdvancedHTMLParser.handle_starttag(self, tagName, attributeList, isSelfClosing)
        self._indexTag(newTag)

        return newTag

Response: Internal method to index and return a new tag.


Instruction:
Can you generate the documentation for the following Python 3 function
def disableIndexing(self):
        '''
            disableIndexing - Disables indexing. Consider using plain AdvancedHTMLParser class.
              Maybe useful in some scenarios where you want to parse, add a ton of elements, then index
              and do a bunch of searching.
        '''
        self.indexIDs = self.indexNames = self.indexClassNames = self.indexTagNames = False
        self._resetIndexInternal()

Response: Disables indexing. Consider using plain AdvancedHTMLParser class.


Instruction:
Implement a function in Python 3 to
add an index for an arbitrary attribute. This will be used by the getElementsByAttr function.

Response:
def addIndexOnAttribute(self, attributeName):
        '''
            addIndexOnAttribute - Add an index for an arbitrary attribute. This will be used by the getElementsByAttr function.
                You should do this prior to parsing, or call reindex. Otherwise it will be blank. "name" and "id" will have no effect.

                @param attributeName <lowercase str> - An attribute name. Will be lowercased.
        '''
        attributeName = attributeName.lower()
        self._otherAttributeIndexes[attributeName] = {}

        def _otherIndexFunction(self, tag):
            thisAttribute = tag.getAttribute(attributeName)
            if thisAttribute is not None:
                if thisAttribute not in self._otherAttributeIndexes[attributeName]:
                    self._otherAttributeIndexes[attributeName][thisAttribute] = []
                self._otherAttributeIndexes[attributeName][thisAttribute].append(tag)

        self.otherAttributeIndexFunctions[attributeName] = _otherIndexFunction


Instruction:
Make a summary of the following Python 3 code
def removeIndexOnAttribute(self, attributeName):
        '''
            removeIndexOnAttribute - Remove an attribute from indexing (for getElementsByAttr function) and remove indexed data.

        @param attributeName <lowercase str> - An attribute name. Will be lowercased. "name" and "id" will have no effect.
        '''
        attributeName = attributeName.lower()
        if attributeName in self.otherAttributeIndexFunctions:
                del self.otherAttributeIndexFunctions[attributeName]
        if attributeName in self._otherAttributeIndexes:
                del self._otherAttributeIndexes[attributeName]

Response: Removes an attribute from indexing and remove indexed data.


Instruction:
Can you tell what is the following Python 3 function doing
def getElementsByTagName(self, tagName, root='root', useIndex=True):
        '''
            getElementsByTagName - Searches and returns all elements with a specific tag name.

                @param tagName <lowercase str> - A lowercase string of the tag name.
                @param root <AdvancedTag/'root'> - Search starting at a specific node, if provided. if string 'root', the root of the parsed tree will be used.
                @param useIndex - If True [default] and tag names are set to be indexed [default, see constructor], only the index will be used. If False, all tags
                  will be searched.
        '''
        (root, isFromRoot) = self._handleRootArg(root)

        if useIndex is True and self.indexTagNames is True:
            elements = self._tagNameMap.get(tagName, []) # Use .get here as to not create a lot of extra indexes on the defaultdict for misses
            if isFromRoot is False:
                _hasTagInParentLine = self._hasTagInParentLine
                elements = [x for x in elements if _hasTagInParentLine(x, root)]

            return TagCollection(elements)

        return AdvancedHTMLParser.getElementsByTagName(self, tagName, root)

Response: getElementsByTagName - Searches and returns all elements with a specific tag name.


Instruction:
How would you explain what the following Python 3 function does
def getElementsByClassName(self, className, root='root', useIndex=True):
        '''
            getElementsByClassName - Searches and returns all elements containing a given class name.

                @param className <str> - A one-word class name
                @param root <AdvancedTag/'root'> - Search starting at a specific node, if provided. if string 'root', the root of the parsed tree will be used.
                @param useIndex <bool> If useIndex is True and class names are indexed [see constructor] only the index will be used. Otherwise a full search is performed.
        '''
        (root, isFromRoot) = self._handleRootArg(root)

        if useIndex is True and self.indexClassNames is True:

            elements = self._classNameMap.get(className, [])

            if isFromRoot is False:
                _hasTagInParentLine = self._hasTagInParentLine
                elements = [x for x in elements if _hasTagInParentLine(x, root)]

            return TagCollection(elements)

        return AdvancedHTMLParser.getElementsByClassName(self, className, root)

Response: getElementsByClassName - Searches and returns all elements containing a given class name.


Instruction:
Explain what the following Python 3 code does
def getElementsByAttr(self, attrName, attrValue, root='root', useIndex=True):
        '''
            getElementsByAttr - Searches the full tree for elements with a given attribute name and value combination. If you want multiple potential values, see getElementsWithAttrValues
               If you want an index on a random attribute, use the addIndexOnAttribute function.

                @param attrName <lowercase str> - A lowercase attribute name
                @param attrValue <str> - Expected value of attribute
                @param root <AdvancedTag/'root'> - Search starting at a specific node, if provided. if string 'root', the root of the parsed tree will be used.
                @param useIndex <bool> If useIndex is True and this specific attribute is indexed [see addIndexOnAttribute] only the index will be used. Otherwise a full search is performed.
        '''
        (root, isFromRoot) = self._handleRootArg(root)

        if useIndex is True and attrName in self._otherAttributeIndexes:

            elements = self._otherAttributeIndexes[attrName].get(attrValue, [])

            if isFromRoot is False:
                _hasTagInParentLine = self._hasTagInParentLine
                elements = [x for x in elements if _hasTagInParentLine(x, root)]

            return TagCollection(elements)

        return AdvancedHTMLParser.getElementsByAttr(self, attrName, attrValue, root)

Response: getElementsByAttr - Searches the full tree for elements with a given attribute name and value combination.


Instruction:
Given the following Python 3 function, write the documentation
def uniqueTags(tagList):
    '''
        uniqueTags - Returns the unique tags in tagList.

            @param tagList list<AdvancedTag> : A list of tag objects.
    '''
    ret = []
    alreadyAdded = set()
    for tag in tagList:
        myUid = tag.getUid()
        if myUid in alreadyAdded:
            continue
        ret.append(tag)
    return TagCollection(ret)

Response: Returns the unique tags in tagList.


Instruction:
Given the following Python 3 function, write the documentation
def toggleAttributesDOM(isEnabled):
    '''
        toggleAttributesDOM - Toggle if the old DOM tag.attributes NamedNodeMap model should be used for the .attributes method, versus

           a more sane direct dict implementation.

            The DOM version is always accessable as AdvancedTag.attributesDOM
            The dict version is always accessable as AdvancedTag.attributesDict

            Default for AdvancedTag.attributes is to be attributesDict implementation.

          @param isEnabled <bool> - If True, .attributes will be changed to use the DOM-provider. Otherwise, it will use the dict provider.
    '''

    if isEnabled:
        AdvancedTag.attributes = AdvancedTag.attributesDOM
    else:
        AdvancedTag.attributes = AdvancedTag.attributesDict

Response: Toggle if the old DOM tag. attributes NamedNodeMap model should be used for the. attributes method.


Instruction:
Write a Python 3 script to
return a clone of this node.

Response:
def cloneNode(self):
        '''
            cloneNode - Clone this node (tag name and attributes). Does not clone children.

            Tags will be equal according to isTagEqual method, but will contain a different internal
            unique id such tag origTag != origTag.cloneNode() , as is the case in JS DOM.
        '''
        return self.__class__(self.tagName, self.getAttributesList(), self.isSelfClosing)


Instruction:
Here you have a function in Python 3, explain what it does
def removeText(self, text):
        '''
            removeText - Removes the first occurace of given text in a text node (i.e. not part of a tag)

            @param text <str> - text to remove

            @return text <str/None> - The text in that block (text node) after remove, or None if not found

            NOTE: To remove a node, @see removeChild
            NOTE: To remove a block (maybe a node, maybe text), @see removeBlock
            NOTE: To remove ALL occuraces of text, @see removeTextAll
        '''
        # TODO: This would be a good candidate for the refactor of text blocks
        removedBlock = None

        # Scan all text blocks for "text"
        blocks = self.blocks
        for i in range(len(blocks)):
            block = blocks[i]

            # We only care about text blocks
            if issubclass(block.__class__, AdvancedTag):
                continue

            if text in block:
                # We have a block that matches.

                # Create a copy of the old text in this block for return
                removedBlock = block[:]
                # Remove first occurance of #text from matched block
                blocks[i] = block.replace(text, '')
                break # remove should only remove FIRST occurace, per other methods

        # Regenerate the "text" property
        self.text = ''.join([thisBlock for thisBlock in blocks if not issubclass(thisBlock.__class__, AdvancedTag)])

        # Return None if no match, otherwise the text previously within the block we removed #text from
        return removedBlock

Response: Removes the first occurace of given text in a text node.


Instruction:
How would you explain what the following Python 3 function does
def removeTextAll(self, text):
        '''
            removeTextAll - Removes ALL occuraces of given text in a text node (i.e. not part of a tag)

            @param text <str> - text to remove

            @return list <str> - All text node containing #text BEFORE the text was removed.
                Empty list if no text removed

            NOTE: To remove a node, @see removeChild
            NOTE: To remove a block (maybe a node, maybe text), @see removeBlock
            NOTE: To remove a single occurace of text, @see removeText
        '''
        # TODO: This would be a good candidate for the refactor of text blocks
        removedBlocks = []

        blocks = self.blocks
        for i in range(len(blocks)):

            block = blocks[i]

            # We only care about text blocks
            if issubclass(block.__class__, AdvancedTag):
                continue

            if text in block:
                # Got a match, save a copy of the text block pre-replace for the return
                removedBlocks.append( block[:] )

                # And replace the text within this matched block
                blocks[i] = block.replace(text, '')

        # Regenerate self.text
        self.text = ''.join([thisBlock for thisBlock in blocks if not issubclass(thisBlock.__class__, AdvancedTag)])

        return removedBlocks

Response: Removes all occuraces of given text in a text node.


Instruction:
Create a Python 3 function for
removing this node from its parent if it has a parent.

Response:
def remove(self):
        '''
            remove - Will remove this node from its parent, if it has a parent (thus taking it out of the HTML tree)

                NOTE: If you are using an IndexedAdvancedHTMLParser, calling this will NOT update the index. You MUST call
                  reindex method manually.

            @return <bool> - While JS DOM defines no return for this function, this function will return True if a
               remove did happen, or False if no parent was set.
        '''
        if self.parentNode:
            self.parentNode.removeChild(self)
            # self.parentNode will now be None by 'removeChild' method
            return True
        return False


Instruction:
Can you generate a brief explanation for the following Python 3 code
def removeBlocks(self, blocks):
        '''
            removeBlock - Removes a list of blocks (the first occurance of each) from the direct children of this node.

            @param blocks  list<str/AdvancedTag> - List of AdvancedTags for tag nodes, else strings for text nodes

            @return The removed blocks in each slot, or None if None removed.

            @see removeChild
            @see removeText

            For multiple, @see removeBlocks
        '''
        ret = []
        for block in blocks:
            if issubclass(block.__class__, AdvancedTag):
                ret.append( self.removeChild(block) )
            else:
                # TODO: Should this just forward to removeText?
                ret.append( self.removeBlock(block) )

        return ret

Response: Removes a list of blocks from the direct children of this node.


Instruction:
Can you write a function in Python 3 where it
appends a child to this element.

Response:
def appendChild(self, child):
        '''
            appendChild - Append a child to this element.

            @param child <AdvancedTag> - Append a child element to this element
        '''

        # Associate parentNode of #child to this tag
        child.parentNode = self

        # Associate owner document to child and all children recursive
        ownerDocument = self.ownerDocument

        child.ownerDocument = ownerDocument
        for subChild in child.getAllChildNodes():
            subChild.ownerDocument = ownerDocument

        # Our tag cannot be self-closing if we have a child tag
        self.isSelfClosing = False

        # Append to both "children" and "blocks"
        self.children.append(child)
        self.blocks.append(child)
        return child


Instruction:
Can you generate the documentation for the following Python 3 function
def appendBlock(self, block):
        '''
            append / appendBlock - Append a block to this element. A block can be a string (text node), or an AdvancedTag (tag node)

            @param <str/AdvancedTag> - block to add

            @return - #block

            NOTE: To add multiple blocks, @see appendBlocks
                  If you know the type, use either @see appendChild for tags or @see appendText for text
        '''
        # Determine block type and call appropriate method
        if isinstance(block, AdvancedTag):
            self.appendNode(block)
        else:
            self.appendText(block)

        return block

Response: Append a block to this element.


Instruction:
Implement a function in Python 3 to
append blocks to this element.

Response:
def appendBlocks(self, blocks):
        '''
            appendBlocks - Append blocks to this element. A block can be a string (text node), or an AdvancedTag (tag node)

            @param blocks list<str/AdvancedTag> - A list, in order to append, of blocks to add.

            @return - #blocks

            NOTE: To add a single block, @see appendBlock
                  If you know the type, use either @see appendChild for tags or @see appendText for text
        '''
        for block in blocks:
            if isinstance(block, AdvancedTag):
                self.appendNode(block)
            else:
                self.appendText(block)

        return blocks


Instruction:
Make a summary of the following Python 3 code
def appendInnerHTML(self, html):
        '''
            appendInnerHTML - Appends nodes from arbitrary HTML as if doing element.innerHTML += 'someHTML' in javascript.

            @param html <str> - Some HTML

            NOTE: If associated with a document ( AdvancedHTMLParser ), the html will use the encoding associated with
                    that document.

            @return - None. A browser would return innerHTML, but that's somewhat expensive on a high-level node.
              So just call .innerHTML explicitly if you need that
        '''

        # Late-binding to prevent circular import
        from .Parser import AdvancedHTMLParser

        # Inherit encoding from the associated document, if any.
        encoding = None
        if self.ownerDocument:
            encoding = self.ownerDocument.encoding

        # Generate blocks (text nodes and AdvancedTag's) from HTML
        blocks = AdvancedHTMLParser.createBlocksFromHTML(html, encoding)

        # Throw them onto this node
        self.appendBlocks(blocks)

Response: Append nodes from arbitrary HTML as if doing element. innerHTML += someHTML in javascript.


Instruction:
How would you implement a function in Python 3 that
removes a child tag from the tree if present.

Response:
def removeChild(self, child):
        '''
            removeChild - Remove a child tag, if present.

                @param child <AdvancedTag> - The child to remove

                @return - The child [with parentNode cleared] if removed, otherwise None.

                NOTE: This removes a tag. If removing a text block, use #removeText function.
                  If you need to remove an arbitrary block (text or AdvancedTag), @see removeBlock

                Removing multiple children? @see removeChildren
        '''
        try:
            # Remove from children and blocks
            self.children.remove(child)
            self.blocks.remove(child)

            # Clear parent node association on child
            child.parentNode = None

            # Clear document reference on removed child and all children thereof
            child.ownerDocument = None
            for subChild in child.getAllChildNodes():
                subChild.ownerDocument = None
            return child
        except ValueError:
            # TODO: What circumstances cause this to be raised? Is it okay to have a partial remove?
            #
            #  Is it only when "child" is not found? Should that just be explicitly tested?
            return None


Instruction:
Write a Python 3 script to
remove multiple child AdvancedTags.

Response:
def removeChildren(self, children):
        '''
            removeChildren - Remove multiple child AdvancedTags.

            @see removeChild

            @return list<AdvancedTag/None> - A list of all tags removed in same order as passed.
                Item is "None" if it was not attached to this node, and thus was not removed.
        '''
        ret = []

        for child in children:
            ret.append( self.removeChild(child) )

        return ret


Instruction:
Make a summary of the following Python 3 code
def removeBlock(self, block):
        '''
            removeBlock - Removes a single block (text node or AdvancedTag) which is a child of this object.

            @param block <str/AdvancedTag> - The block (text node or AdvancedTag) to remove.

            @return Returns the removed block if one was removed, or None if requested block is not a child of this node.

            NOTE: If you know you are going to remove an AdvancedTag, @see removeChild
                  If you know you are going to remove a text node,    @see removeText

            If removing multiple blocks, @see removeBlocks
        '''
        if issubclass(block.__class__, AdvancedTag):
            return self.removeChild(block)
        else:
            return self.removeText(block)

Response: Removes a single block which is a child of this object.


Instruction:
Here you have a function in Python 3, explain what it does
def insertBefore(self, child, beforeChild):
        '''
            insertBefore - Inserts a child before #beforeChild

                @param child <AdvancedTag/str> - Child block to insert

                @param beforeChild <AdvancedTag/str> - Child block to insert before. if None, will  be appended

            @return - The added child. Note, if it is a text block (str), the return isl NOT be linked by reference.

            @raises ValueError - If #beforeChild is defined and is not a child of this node

        '''
        # When the second arg is null/None, the node is appended. The argument is required per JS API, but null is acceptable..
        if beforeChild is None:
            return self.appendBlock(child)

        # If #child is an AdvancedTag, we need to add it to both blocks and children.
        isChildTag = isTagNode(child)

        myBlocks = self.blocks
        myChildren = self.children

        # Find the index #beforeChild falls under current element
        try:
            blocksIdx =  myBlocks.index(beforeChild)
            if isChildTag:
                childrenIdx = myChildren.index(beforeChild)
        except ValueError:
            # #beforeChild is not a child of this element. Raise error.
            raise ValueError('Provided "beforeChild" is not a child of element, cannot insert.')

        # Add to blocks in the right spot
        self.blocks = myBlocks[:blocksIdx] + [child] + myBlocks[blocksIdx:]
        # Add to child in the right spot
        if isChildTag:
            self.children = myChildren[:childrenIdx] + [child] + myChildren[childrenIdx:]

        return child

Response: Insert a child into the node with the highest priority.


Instruction:
Here you have a function in Python 3, explain what it does
def insertAfter(self, child, afterChild):
        '''
            insertAfter - Inserts a child after #afterChild

                @param child <AdvancedTag/str> - Child block to insert

                @param afterChild <AdvancedTag/str> - Child block to insert after. if None, will  be appended

            @return - The added child. Note, if it is a text block (str), the return isl NOT be linked by reference.
        '''

        # If after child is null/None, just append
        if afterChild is None:
            return self.appendBlock(child)

        isChildTag = isTagNode(child)

        myBlocks = self.blocks
        myChildren = self.children

        # Determine where we need to insert this both in "blocks" and, if a tag, "children"
        try:
            blocksIdx =  myBlocks.index(afterChild)
            if isChildTag:
                childrenIdx = myChildren.index(afterChild)
        except ValueError:
            raise ValueError('Provided "afterChild" is not a child of element, cannot insert.')

        # Append child to requested spot
        self.blocks = myBlocks[:blocksIdx+1] + [child] + myBlocks[blocksIdx+1:]
        if isChildTag:
            self.children = myChildren[:childrenIdx+1] + [child] + myChildren[childrenIdx+1:]

        return child

Response: Insert a child into the tree.


Instruction:
Write a Python 3 function for
getting the last child block text or tag

Response:
def lastChild(self):
        '''
            lastChild - property, Get the last child block, text or tag

                @return <str/AdvancedTag/None> - The last child block, or None if no child blocks
        '''
        blocks = object.__getattribute__(self, 'blocks')
        # First block is empty string for indent, but don't hardcode incase that changes
        if blocks[0] == '':
           firstIdx = 1
        else:
           firstIdx = 0

        if len(blocks) <= firstIdx:
            return None

        return blocks[-1]


Instruction:
Implement a function in Python 3 to
return the next sibling that is an element. This is the next sibling that is an element.

Response:
def nextElementSibling(self):
        '''
            nextElementSibling - Returns the next sibling that is an element.
                This is the tag node following this node in the parent's list of children

                @return <None/AdvancedTag> - None if there are no children (tag) in the parent after this node,
                                                    Otherwise the following element (tag)
        '''
        parentNode = self.parentNode

        # If no parent, no siblings
        if not parentNode:
            return None

        # Determine the index in children
        myElementIdx = parentNode.children.index(self)

        # If we are last child, no next sibling
        if myElementIdx == len(parentNode.children) - 1:
            return None

        # Else, return the next child in parent
        return parentNode.children[myElementIdx+1]


Instruction:
Can you create a Python 3 function that
returns the previous sibling of this node in the parent s list

Response:
def previousSibling(self):
        '''
            previousSibling - Returns the previous sibling. This would be the previous node (text or tag) in the parent's list

                This could be text or an element. use previousSiblingElement to ensure element

                @return <None/str/AdvancedTag> - None if there are no nodes (text or tag) in the parent before this node,
                                                    Otherwise the previous node (text or tag)
        '''
        parentNode = self.parentNode

        # If no parent, no previous sibling
        if not parentNode:
            return None

        # Determine block index on parent of this node
        myBlockIdx = parentNode.blocks.index(self)

        # If we are the first, no previous sibling
        if myBlockIdx == 0:
            return None

        # Else, return the previous block in parent
        return parentNode.blocks[myBlockIdx-1]


Instruction:
Can you generate the documentation for the following Python 3 function
def previousElementSibling(self):
        '''
            previousElementSibling - Returns the previous  sibling  that is an element.

                                        This is the previous tag node in the parent's list of children

                @return <None/AdvancedTag> - None if there are no children (tag) in the parent before this node,
                                                    Otherwise the previous element (tag)

        '''
        parentNode = self.parentNode

        # If no parent, no siblings
        if not parentNode:
            return None

        # Determine this node's index in the children of parent
        myElementIdx = parentNode.children.index(self)

        # If we are the first child, no previous element
        if myElementIdx == 0:
            return None

        # Else, return previous element tag
        return parentNode.children[myElementIdx-1]

Response:
Returns the previous sibling that is an element.

 clf - The node that is an element.

 clf - The node that is an element.

 clf - The node that is an element.

MimeType This is the previous element in the parent s list of children

                This is the previous element in the parent s list of children
 ArcGIS elements.


Instruction:
Given the following Python 3 function, write the documentation
def tagBlocks(self):
        '''
            tagBlocks - Property.
                        Returns all the blocks which are direct children of this node, where that block is a tag (not text)

                NOTE: This is similar to .children , and you should probably use .children instead except within this class itself

                @return list<AdvancedTag> - A list of direct children which are tags.
        '''
        myBlocks = self.blocks

        return [block for block in myBlocks if issubclass(block.__class__, AdvancedTag)]

Response:
Property.
                        Returns all the blocks which are direct children of this node where that block is a tag.


Instruction:
Can you generate the documentation for the following Python 3 function
def getBlocksTags(self):
        '''
            getBlocksTags - Returns a list of tuples referencing the blocks which are direct children of this node, and the block is an AdvancedTag.

                The tuples are ( block, blockIdx ) where "blockIdx" is the index of self.blocks wherein the tag resides.

                @return list< tuple(block, blockIdx) > - A list of tuples of child blocks which are tags and their index in the self.blocks list
        '''
        myBlocks = self.blocks

        return [ (myBlocks[i], i) for i in range( len(myBlocks) ) if issubclass(myBlocks[i].__class__, AdvancedTag) ]

Response: getBlocksTags - Returns a list of tuples referencing the blocks which are direct children of this node and the block is an AdvancedTag.


Instruction:
Can you tell what is the following Python 3 function doing
def textBlocks(self):
        '''
            textBlocks - Property.
                        Returns all the blocks which are direct children of this node, where that block is a text (not a tag)

                @return list<AdvancedTag> - A list of direct children which are text.
        '''
        myBlocks = self.blocks

        return [block for block in myBlocks if not issubclass(block.__class__, AdvancedTag)]

Response: Property. vsetTextBlocks Returns all the blocks which are direct children of this node where that block is a text.


Instruction:
Can you generate the documentation for the following Python 3 function
def containsUid(self, uid):
        '''
            containsUid - Check if the uid (unique internal ID) appears anywhere as a direct child to this node, or the node itself.

                @param uid <uuid.UUID> - uuid to check

            @return <bool> - True if #uid is this node's uid, or is the uid of any children at any level down
        '''
        # Check if this node is the match
        if self.uid == uid:
            return True

        # Scan all children
        for child in self.children:
            if child.containsUid(uid):
                return True

        return False

Response: Check if the uid appears anywhere as a direct child to this node or the node itself.


Instruction:
Make a summary of the following Python 3 code
def getAllChildNodes(self):
        '''
            getAllChildNodes - Gets all the children, and their children,
               and their children, and so on, all the way to the end as a TagCollection.

               Use .childNodes for a regular list

            @return TagCollection<AdvancedTag> - A TagCollection of all children (and their children recursive)
        '''

        ret = TagCollection()

        # Scan all the children of this node
        for child in self.children:
            # Append each child
            ret.append(child)

            # Append children's children recursive
            ret += child.getAllChildNodes()

        return ret

Response: getAllChildNodes - Gets all the children and their children and their children recursive


Instruction:
Can you tell what is the following Python 3 function doing
def getAllNodeUids(self):
        '''
            getAllNodeUids - Returns all the unique internal IDs from getAllChildNodeUids, but also includes this tag's uid

            @return set<uuid.UUID> A set of uuid objects
        '''
        # Start with a set including this tag's uuid
        ret = { self.uid }

        ret.update(self.getAllChildNodeUids())

        return ret

Response: getAllNodeUids - Returns all the unique internal IDs from getAllChildNodeUids but also includes this tag s uid


Instruction:
Make a summary of the following Python 3 code
def getPeers(self):
        '''
            getPeers - Get elements who share a parent with this element

            @return - TagCollection of elements
        '''
        parentNode = self.parentNode
        # If no parent, no peers
        if not parentNode:
            return None

        peers = parentNode.children

        # Otherwise, get all children of parent excluding this node
        return TagCollection([peer for peer in peers if peer is not self])

Response: getPeers - Get elements who share a parent with this element


Instruction:
Can you generate a brief explanation for the following Python 3 code
def getStartTag(self):
        '''
            getStartTag - Returns the start tag represented as HTML

            @return - String of start tag with attributes
        '''
        attributeStrings = []
        # Get all attributes as a tuple (name<str>, value<str>)
        for name, val in self._attributes.items():
            # Get all attributes
            if val:
                val = tostr(val)

            # Only binary attributes have a "present/not present"
            if val or name not in TAG_ITEM_BINARY_ATTRIBUTES:
                # Escape any quotes found in the value
                val = escapeQuotes(val)

                # Add a name="value" to the resulting string
                attributeStrings.append('%s="%s"' %(name, val) )
            else:
                # This is a binary attribute, and thus only includes the name ( e.x. checked )
                attributeStrings.append(name)

        # Join together all the attributes in @attributeStrings list into a string
        if attributeStrings:
            attributeString = ' ' + ' '.join(attributeStrings)
        else:
            attributeString = ''

        # If this is a self-closing tag, generate like  <tag attr1="val" attr2="val2" />  with the close "/>"
        # Include the indent prior to tag opening
        if self.isSelfClosing is False:
            return "%s<%s%s >" %(self._indent, self.tagName, attributeString)
        else:
            return "%s<%s%s />" %(self._indent, self.tagName, attributeString)

Response: Returns the start tag represented as HTML


Instruction:
Write a Python 3 function that can
return the end tag representation as HTML string

Response:
def getEndTag(self):
        '''
            getEndTag - returns the end tag representation as HTML string

            @return - String of end tag
        '''
        # If this is a self-closing tag, we have no end tag (opens and closes in the start)
        if self.isSelfClosing is True:
            return ''

        tagName = self.tagName

        # Do not add any indentation to the end of preformatted tags.
        if self._indent and tagName in PREFORMATTED_TAGS:
            return "</%s>" %(tagName, )

        # Otherwise, indent the end of this tag
        return "%s</%s>" %(self._indent, tagName)


Instruction:
Make a summary of the following Python 3 code
def innerHTML(self):
        '''
            innerHTML - Returns an HTML string of the inner contents of this tag, including children.

            @return - String of inner contents HTML
        '''

        # If a self-closing tag, there are no contents
        if self.isSelfClosing is True:
            return ''

        # Assemble all the blocks.
        ret = []

        # Iterate through blocks
        for block in self.blocks:
            # For each block:
            #   If a tag, append the outer html (start tag, contents, and end tag)
            #   Else, append the text node directly

            if isinstance(block, AdvancedTag):
                ret.append(block.outerHTML)
            else:
                ret.append(block)

        return ''.join(ret)

Response: Returns an HTML string of the inner contents of this tag including children.


Instruction:
Write a Python 3 script for
getting an attribute value on this tag.

Response:
def getAttribute(self, attrName, defaultValue=None):
        '''
            getAttribute - Gets an attribute on this tag. Be wary using this for classname, maybe use addClass/removeClass. Attribute names are all lowercase.
                @return - The attribute value, or None if none exists.
        '''

        if attrName in TAG_ITEM_BINARY_ATTRIBUTES:
            if attrName in self._attributes:
                attrVal = self._attributes[attrName]
                if not attrVal:
                    return True # Empty valued binary attribute

                return attrVal # optionally-valued binary attribute
            else:
                return False
        else:
            return self._attributes.get(attrName, defaultValue)


Instruction:
Given the following Python 3 function, write the documentation
def getAttributesList(self):
        '''
            getAttributesList - Get a copy of all attributes as a list of tuples (name, value)

              ALL values are converted to string and copied, so modifications will not affect the original attributes.
                If you want types like "style" to work as before, you'll need to recreate those elements (like StyleAttribute(strValue) ).

              @return list< tuple< str(name), str(value) > > - A list of tuples of attrName, attrValue pairs, all converted to strings.

                This is suitable for passing back into AdvancedTag when creating a new tag.
        '''
        return [ (tostr(name)[:], tostr(value)[:]) for name, value in self._attributes.items() ]

Response: getAttributesList - Get a copy of all attributes as a list of tuples name and value pairs all converted to strings and all values are copied to strings


Instruction:
Can you generate the documentation for the following Python 3 function
def getAttributesDict(self):
        '''
            getAttributesDict - Get a copy of all attributes as a dict map of name -> value

              ALL values are converted to string and copied, so modifications will not affect the original attributes.
                If you want types like "style" to work as before, you'll need to recreate those elements (like StyleAttribute(strValue) ).

              @return <dict ( str(name), str(value) )> - A dict of attrName to attrValue , all as strings and copies.
        '''

        return { tostr(name)[:] : tostr(value)[:] for name, value in self._attributes.items() }

Response: Get a copy of all attributes as a dict of name - > value


Instruction:
Make a summary of the following Python 3 code
def hasAttribute(self, attrName):
        '''
            hasAttribute - Checks for the existance of an attribute. Attribute names are all lowercase.

                @param attrName <str> - The attribute name

                @return <bool> - True or False if attribute exists by that name
        '''
        attrName = attrName.lower()

        # Check if requested attribute is present on this node
        return bool(attrName in self._attributes)

Response: Checks if the attribute name is present on this node.


Instruction:
Create a Python 3 function for
removing an attribute by name.

Response:
def removeAttribute(self, attrName):
        '''
            removeAttribute - Removes an attribute, by name.

            @param attrName <str> - The attribute name

        '''
        attrName = attrName.lower()

        # Delete provided attribute name ( #attrName ) from attributes map
        try:
            del self._attributes[attrName]
        except KeyError:
            pass


Instruction:
Write a Python 3 function that can
add a class name to the end of the class attribute.

Response:
def addClass(self, className):
        '''
            addClass - append a class name to the end of the "class" attribute, if not present

                @param className <str> - The name of the class to add
        '''
        className = stripWordsOnly(className)

        if not className:
            return None

        if ' ' in className:
            # Multiple class names passed, do one at a time
            for oneClassName in className.split(' '):
                self.addClass(oneClassName)
            return

        myClassNames = self._classNames

        # Do not allow duplicates
        if className in myClassNames:
            return

        # Regenerate "classNames" and "class" attr.
        #   TODO: Maybe those should be properties?
        myClassNames.append(className)

        return None


Instruction:
Can you tell what is the following Python 3 function doing
def removeClass(self, className):
        '''
            removeClass - remove a class name if present. Returns the class name if  removed, otherwise None.

                @param className <str> - The name of the class to remove

                @return <str> - The class name removed if one was removed, otherwise None if #className wasn't present
        '''
        className = stripWordsOnly(className)

        if not className:
            return None

        if ' ' in className:
            # Multiple class names passed, do one at a time
            for oneClassName in className.split(' '):
                self.removeClass(oneClassName)
            return

        myClassNames = self._classNames

        # If not present, this is a no-op
        if className not in myClassNames:
            return None

        myClassNames.remove(className)

        return className

Response: Removes a class name if present. Returns the class name if removed otherwise None.


Instruction:
Create a Python 3 function for
returning a dictionary of style attribute value pairs.

Response:
def getStyleDict(self):
        '''
            getStyleDict - Gets a dictionary of style attribute/value pairs.

            @return - OrderedDict of "style" attribute.
        '''

        # TODO: This method is not used and does not appear in any tests.

        styleStr = (self.getAttribute('style') or '').strip()
        styles = styleStr.split(';') # Won't work for strings containing semicolon..
        styleDict = OrderedDict()
        for item in styles:
            try:
                splitIdx = item.index(':')
                name = item[:splitIdx].strip().lower()
                value = item[splitIdx+1:].strip()
                styleDict[name] = value
            except:
                continue

        return styleDict


Instruction:
Here you have a function in Python 3, explain what it does
def setStyle(self, styleName, styleValue):
        '''
            setStyle - Sets a style param. Example: "display", "block"

                If you need to set many styles on an element, use setStyles instead.
                It takes a dictionary of attribute, value pairs and applies it all in one go (faster)

                To remove a style, set its value to empty string.
                When all styles are removed, the "style" attribute will be nullified.

            @param styleName - The name of the style element
            @param styleValue - The value of which to assign the style element

            @return - String of current value of "style" after change is made.
        '''
        myAttributes = self._attributes

        if 'style' not in myAttributes:
            myAttributes['style'] = "%s: %s" %(styleName, styleValue)
        else:
            setattr(myAttributes['style'], styleName, styleValue)

Response: Sets a style attribute of the element containing the specified name and value.


Instruction:
Here you have a function in Python 3, explain what it does
def setStyles(self, styleUpdatesDict):
        '''
            setStyles - Sets one or more style params.
                This all happens in one shot, so it is much much faster than calling setStyle for every value.

                To remove a style, set its value to empty string.
                When all styles are removed, the "style" attribute will be nullified.

            @param styleUpdatesDict - Dictionary of attribute : value styles.

            @return - String of current value of "style" after change is made.
        '''
        setStyleMethod = self.setStyle
        for newName, newValue in styleUpdatesDict.items():
            setStyleMethod(newName, newValue)

        return self.style

Response: Sets the style of the elements in styleUpdatesDict.


Instruction:
Create a Python 3 function for
searching children of this tag for a tag containing an id. Returns the AdvancedTag or None if no such tag exists.

Response:
def getElementById(self, _id):
        '''
            getElementById - Search children of this tag for a tag containing an id

            @param _id - String of id

            @return - AdvancedTag or None
        '''
        for child in self.children:
            if child.getAttribute('id') == _id:
                return child
            found = child.getElementById(_id)
            if found is not None:
                return found
        return None


Instruction:
Can you tell what is the following Python 3 function doing
def getElementsByAttr(self, attrName, attrValue):
        '''
            getElementsByAttr - Search children of this tag for tags with an attribute name/value pair

            @param attrName - Attribute name (lowercase)
            @param attrValue - Attribute value

            @return - TagCollection of matching elements
        '''
        elements = []
        for child in self.children:
            if child.getAttribute(attrName) == attrValue:
                elements.append(child)
            elements += child.getElementsByAttr(attrName, attrValue)
        return TagCollection(elements)

Response:
getElementsByAttr - Search children of this tag for tags with an attribute name and value pair
            - Attribute name to use as the attribute name and value pair
            - Attribute value to use as the attribute value


Instruction:
Here you have a function in Python 3, explain what it does
def getElementsByClassName(self, className):
        '''
            getElementsByClassName - Search children of this tag for tags containing a given class name

            @param className - Class name

            @return - TagCollection of matching elements
        '''
        elements = []
        for child in self.children:
            if child.hasClass(className) is True:
                elements.append(child)
            elements += child.getElementsByClassName(className)
        return TagCollection(elements)

Response:
getElementsByClassName - Search children of this tag for tags containing a given class name
            - Tag class name
            - Class name of the tag


Instruction:
Can you generate a brief explanation for the following Python 3 code
def getFirstElementCustomFilter(self, filterFunc):
        '''
            getFirstElementCustomFilter - Gets the first element which matches a given filter func.

                Scans first child, to the bottom, then next child to the bottom, etc. Does not include "self" node.

            @param filterFunc <function> - A function or lambda expression that should return "True" if the passed node matches criteria.

            @return <AdvancedTag/None> - First match, or None

            @see getElementsCustomFilter
        '''

        for child in self.children:
            if filterFunc(child) is True:
                return child

            childSearchResult = child.getFirstElementCustomFilter(filterFunc)
            if childSearchResult is not None:
                return childSearchResult

        return None

Response: Gets the first element which matches a given filterFunc.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def getParentElementCustomFilter(self, filterFunc):
        '''
            getParentElementCustomFilter - Runs through parent on up to document root, returning the

                                              first tag which filterFunc(tag) returns True.

                @param filterFunc <function/lambda> - A function or lambda expression that should return "True" if the passed node matches criteria.

                @return <AdvancedTag/None> - First match, or None

                @see getFirstElementCustomFilter for matches against children
        '''
        parentNode = self.parentNode
        while parentNode:

            if filterFunc(parentNode) is True:
                return parentNode

            parentNode = parentNode.parentNode

        return None

Response: This method returns the first tag which filterFunc returns True.


Instruction:
Make a summary of the following Python 3 code
def getPeersWithAttrValues(self, attrName, attrValues):
        '''
            getPeersWithAttrValues - Gets peers (elements on same level) whose attribute given by #attrName
                are in the list of possible vaues #attrValues

            @param attrName - Name of attribute
            @param attrValues - List of possible values which will match

            @return - None if no parent element (error condition), otherwise a TagCollection of peers that matched.
        '''
        peers = self.peers
        if peers is None:
            return None
        return TagCollection([peer for peer in peers if peer.getAttribute(attrName) in attrValues])

Response: Returns a TagCollection of peers whose attribute given by attrName is in the list of possible values which will match attrValues.


Instruction:
Can you generate the documentation for the following Python 3 function
def getPeersByName(self, name):
        '''
            getPeersByName - Gets peers (elements on same level) with a given name

            @param name - Name to match

            @return - None if no parent element (error condition), otherwise a TagCollection of peers that matched.
        '''
        peers = self.peers
        if peers is None:
            return None
        return TagCollection([peer for peer in peers if peer.name == name])

Response: Returns a TagCollection of peers with a given name.


Instruction:
Can you implement a function in Python 3 that
compares two tags and return True if they are the same.

Response:
def isTagEqual(self, other):
        '''
            isTagEqual - Compare if a tag contains the same tag name and attributes as another tag,

                i.e. if everything between < and > parts of this tag are the same.

                Does NOT compare children, etc. Does NOT compare if these are the same exact tag in the html (use regular == operator for that)

                So for example:

                    tag1 = document.getElementById('something')
                    tag2 = copy.copy(tag1)

                    tag1 == tag2          # This is False
                    tag1.isTagEqual(tag2) # This is True

                @return bool - True if tags have the same name and attributes, otherwise False
        '''
#        if type(other) != type(self):
#            return False

#       NOTE: Instead of type check,
#          just see if we can get the needed attributes in case subclassing
        try:
            if self.tagName != other.tagName:
                return False

            myAttributes = self._attributes
            otherAttributes = other._attributes

            attributeKeysSelf = list(myAttributes.keys())
            attributeKeysOther = list(otherAttributes.keys())
        except:
            return False

        # Check that we have all the same attribute names
        if set(attributeKeysSelf) != set(attributeKeysOther):
            return False

        for key in attributeKeysSelf:

            if myAttributes.get(key) != otherAttributes.get(key):
                return False

        return True


Instruction:
How would you implement a function in Python 3 that
appends an item to this tag collection

Response:
def append(self, tag):
        '''
            append - Append an item to this tag collection

            @param tag - an AdvancedTag
        '''
        list.append(self, tag)
        self.uids.add(tag.uid)


Instruction:
Create a Python 3 function to
remove an item from this tag collection

Response:
def remove(self, toRemove):
        '''
            remove - Remove an item from this tag collection

            @param toRemove - an AdvancedTag
        '''
        list.remove(self, toRemove)
        self.uids.remove(toRemove.uid)


Instruction:
Can you implement a function in Python 3 that
filters only the immediate objects contained within this Collection against a function or lambda expression that returns True to have that element

Response:
def filterCollection(self, filterFunc):
        '''
            filterCollection - Filters only the immediate objects contained within this Collection against a function, not including any children

            @param filterFunc <function> - A function or lambda expression that returns True to have that element match

            @return TagCollection<AdvancedTag>
        '''
        ret = TagCollection()
        if len(self) == 0:
            return ret

        for tag in self:
            if filterFunc(tag) is True:
                ret.append(tag)

        return ret


Instruction:
Can you tell what is the following Python 3 function doing
def getElementsByClassName(self, className):
        '''
            getElementsByClassName - Get elements within this collection containing a specific class name

            @param className - A single class name

            @return - TagCollection of unique elements within this collection tagged with a specific class name
        '''
        ret = TagCollection()
        if len(self) == 0:
            return ret
        _cmpFunc = lambda tag : tag.hasClass(className)
        for tag in self:
            TagCollection._subset(ret, _cmpFunc, tag)

        return ret

Response: getElementsByClassName - Get elements within this collection containing a specific class name


Instruction:
Can you generate the documentation for the following Python 3 function
def getElementById(self, _id):
        '''
            getElementById - Gets an element within this collection by id

            @param _id - string of "id" attribute

            @return - a single tag matching the id, or None if none found
        '''
        for tag in self:
            if tag.id == _id:
                return tag
            for subtag in tag.children:
                tmp = subtag.getElementById(_id)
                if tmp is not None:
                    return tmp
        return None

Response: Gets an element within this collection by id


Instruction:
How would you explain what the following Python 3 function does
def getElementsByAttr(self, attr, value):
        '''
            getElementsByAttr - Get elements within this collection posessing a given attribute/value pair

            @param attr - Attribute name (lowercase)
            @param value - Matching value

            @return - TagCollection of all elements matching name/value
        '''
        ret = TagCollection()
        if len(self) == 0:
            return ret

        attr = attr.lower()
        _cmpFunc = lambda tag : tag.getAttribute(attr) == value
        for tag in self:
            TagCollection._subset(ret, _cmpFunc, tag)

        return ret

Response:
getElementsByAttr - Get elements within this collection posessing a given attribute value pair
            - Name of the attribute to search for value - Value of the attribute to search for


Instruction:
Can you generate a brief explanation for the following Python 3 code
def getElementsWithAttrValues(self, attr, values):
        '''
            getElementsWithAttrValues - Get elements within this collection possessing an attribute name matching one of several values

            @param attr <lowercase str> - Attribute name (lowerase)
            @param values set<str> - Set of possible matching values

            @return - TagCollection of all elements matching criteria
        '''
        ret = TagCollection()
        if len(self) == 0:
            return ret

        if type(values) != set:
            values = set(values)

        attr = attr.lower()
        _cmpFunc = lambda tag : tag.getAttribute(attr) in values
        for tag in self:
            TagCollection._subset(ret, _cmpFunc, tag)

        return ret

Response: getElementsWithAttrValues - Get elements within this collection possessing an attribute name matching one of several values


Instruction:
Can you tell what is the following Python 3 function doing
def getElementsCustomFilter(self, filterFunc):
        '''
            getElementsCustomFilter - Get elements within this collection that match a user-provided function.

            @param filterFunc <function> - A function that returns True if the element matches criteria

            @return - TagCollection of all elements that matched criteria
        '''
        ret = TagCollection()
        if len(self) == 0:
            return ret

        _cmpFunc = lambda tag : filterFunc(tag) is True
        for tag in self:
            TagCollection._subset(ret, _cmpFunc, tag)

        return ret

Response: getElementsCustomFilter - Get elements within this collection that match a user - provided function.


Instruction:
Write a Python 3 function that can
get all the nodes and all their children for every node within this collection

Response:
def getAllNodes(self):
        '''
            getAllNodes - Gets all the nodes, and all their children for every node within this collection
        '''
        ret = TagCollection()

        for tag in self:
            ret.append(tag)
            ret += tag.getAllChildNodes()

        return ret


Instruction:
Can you generate the documentation for the following Python 3 function
def contains(self, em):
        '''
            contains - Check if #em occurs within any of the elements within this list, as themselves or as a child, any
               number of levels down.

               To check if JUST an element is contained within this list directly, use the "in" operator.

            @param em <AdvancedTag> - Element of interest

            @return <bool> - True if contained, otherwise False
        '''

        for node in self:
            if node.contains(em):
                return True

        return False

Response: Check if an element is contained within this list.


Instruction:
Write a Python 3 script for
checking if the uid of the element in this list is contained in any of the levels down.

Response:
def containsUid(self, uid):
        '''
            containsUid - Check if #uid is the uid (unique internal identifier) of any of the elements within this list,
              as themselves or as a child, any number of levels down.

            @param uid <uuid.UUID> - uuid of interest

            @return <bool> - True if contained, otherwise False
        '''
        for node in self:
            if node.containsUid(uid):
                return True

        return False


Instruction:
Can you tell what is the following Python 3 function doing
def filterAll(self, **kwargs):
        '''
            filterAll aka filterAllAnd - Perform a filter operation on ALL nodes in this collection and all their children.

            Results must match ALL the filter criteria. for ANY, use the *Or methods

            For just the nodes in this collection, use "filter" or "filterAnd" on a TagCollection

            For special filter keys, @see #AdvancedHTMLParser.AdvancedHTMLParser.filter

            Requires the QueryableList module to be installed (i.e. AdvancedHTMLParser was installed
              without '--no-deps' flag.)

            For alternative without QueryableList,
              consider #AdvancedHTMLParser.AdvancedHTMLParser.find method or the getElement* methods

            @return TagCollection<AdvancedTag>
        '''
        if canFilterTags is False:
            raise NotImplementedError('filter methods requires QueryableList installed, it is not. Either install QueryableList, or try the less-robust "find" method, or the getElement* methods.')

        allNodes = self.getAllNodes()

        filterableNodes = FilterableTagCollection(allNodes)

        return filterableNodes.filterAnd(**kwargs)

Response: Filter all the tags in this collection and all their children.


Instruction:
Can you tell what is the following Python 3 function doing
def filterAllOr(self, **kwargs):
        '''
            filterAllOr - Perform a filter operation on ALL nodes in this collection and all their children.

            Results must match ANY the filter criteria. for ALL, use the *And methods

            For just the nodes in this collection, use "filterOr" on a TagCollection

            For special filter keys, @see #AdvancedHTMLParser.AdvancedHTMLParser.filter

            Requires the QueryableList module to be installed (i.e. AdvancedHTMLParser was installed
              without '--no-deps' flag.)

            For alternative without QueryableList,
              consider #AdvancedHTMLParser.AdvancedHTMLParser.find method or the getElement* methods

            @return TagCollection<AdvancedTag>
        '''
        if canFilterTags is False:
            raise NotImplementedError('filter methods requires QueryableList installed, it is not. Either install QueryableList, or try the less-robust "find" method, or the getElement* methods.')

        allNodes = self.getAllNodes()

        filterableNodes = FilterableTagCollection(allNodes)

        return filterableNodes.filterOr(**kwargs)

Response: Filter all tags in this collection and all their children.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def handle_endtag(self, tagName):
        '''
            handle_endtag - Internal for parsing
        '''
        inTag = self._inTag
        try:
            # Handle closing tags which should have been closed but weren't
            foundIt = False
            for i in range(len(inTag)):
                if inTag[i].tagName == tagName:
                    foundIt = True
                    break

            if not foundIt:
                sys.stderr.write('WARNING: found close tag with no matching start.\n')
                return

            while inTag[-1].tagName != tagName:
                oldTag = inTag.pop()
                if oldTag.tagName in PREFORMATTED_TAGS:
                    self.inPreformatted -= 1

                self.currentIndentLevel -= 1

            inTag.pop()
            if tagName != INVISIBLE_ROOT_TAG:
                self.currentIndentLevel -= 1
            if tagName in PREFORMATTED_TAGS:
                self.inPreformatted -= 1
        except:
            pass

Response: handle_endtag - Internal for parsing


Instruction:
Explain what the following Python 3 code does
def getStartTag(self, *args, **kwargs):
        '''
            getStartTag - Override the end-spacing rules

              @see AdvancedTag.getStartTag
        '''

        ret = AdvancedTag.getStartTag(self, *args, **kwargs)

        if ret.endswith(' >'):
            ret = ret[:-2] + '>'
        elif object.__getattribute__(self, 'slimSelfClosing') and ret.endswith(' />'):
            ret = ret[:-3] + '/>'

        return ret

Response:
Override the end - spacing rules
            getStartTag - Override the end - spacing rules
            getStartTag - Override the end - spacing rules
            getStartTag - Override the end - spacing rules
            getStartTag
              @see AdvancedTag. getStartTag


Instruction:
Make a summary of the following Python 3 code
def stripIEConditionals(contents, addHtmlIfMissing=True):
    '''
        stripIEConditionals - Strips Internet Explorer conditional statements.

        @param contents <str> - Contents String
        @param addHtmlIfMissing <bool> - Since these normally encompass the "html" element, optionally add it back if missing.
    '''
    allMatches = IE_CONDITIONAL_PATTERN.findall(contents)
    if not allMatches:
        return contents

    for match in allMatches:
        contents = contents.replace(match, '')

    if END_HTML.match(contents) and not START_HTML.match(contents):
        contents = addStartTag(contents, '<html>')

    return contents

Response: Strips Internet Explorer conditional statements from the contents string.


Instruction:
Can you tell what is the following Python 3 function doing
def addStartTag(contents, startTag):
    '''
        addStartTag - Safetly add a start tag to the document, taking into account the DOCTYPE

        @param contents <str> - Contents
        @param startTag <str> - Fully formed tag, i.e. <html>
    '''

    matchObj = DOCTYPE_MATCH.match(contents)
    if matchObj:
        idx = matchObj.end()
    else:
        idx = 0
    return "%s\n%s\n%s" %(contents[:idx], startTag, contents[idx:])

Response: This function will take a list of contents and startTag and add it to the document.


Instruction:
How would you implement a function in Python 3 that
converts a value to either a string of true or false

Response:
def convertToBooleanString(val=None):
    '''
        convertToBooleanString - Converts a value to either a string of "true" or "false"

            @param val <int/str/bool> - Value
    '''
    if hasattr(val, 'lower'):
        val = val.lower()

        # Technically, if you set one of these attributes (like "spellcheck") to a string of 'false',
        #   it gets set to true. But we will retain "false" here.
        if val in ('false', '0'):
            return 'false'
        else:
            return 'true'

    try:
        if bool(val):
            return "true"
    except:
        pass

    return "false"


Instruction:
Given the following Python 3 function, write the documentation
def convertBooleanStringToBoolean(val=None):
    '''
        convertBooleanStringToBoolean - Convert from a boolean attribute (string "true" / "false" ) into a booelan
    '''
    if not val:
        return False

    if hasattr(val, 'lower'):
        val = val.lower()

    if val == "false":
        return False
    return True

Response: Convert a boolean attribute to a booelan


Instruction:
Here you have a function in Python 3, explain what it does
def _handleInvalid(invalidDefault):
    '''
        _handleInvalid - Common code for raising / returning an invalid value

            @param invalidDefault <None/str/Exception> - The value to return if "val" is not empty string/None
                                                           and "val" is not in #possibleValues

                     If instantiated Exception (like ValueError('blah')):  Raise this exception

                     If an Exception type ( like ValueError ) - Instantiate and raise this exception type

                     Otherwise, use this raw value
    '''
    # If not
    #   If an instantiated Exception, raise that exception
    try:
        isInstantiatedException = bool( issubclass(invalidDefault.__class__, Exception) )
    except:
        isInstantiatedException = False

    if isInstantiatedException:
        raise invalidDefault
    else:
        try:
            isExceptionType = bool( issubclass( invalidDefault, Exception) )
        except TypeError:
            isExceptionType = False

        #   If an Exception type, instantiate and raise
        if isExceptionType:
            raise invalidDefault()
        else:
        #   Otherwise, just return invalidDefault itself
            return invalidDefault

Response: Internal helper function to handle exceptions raised by the base class


Instruction:
Create a Python 3 function to
convert input value to one of several possible values in the database.

Response:
def convertPossibleValues(val, possibleValues, invalidDefault, emptyValue=''):
    '''
        convertPossibleValues - Convert input value to one of several possible values,

                                    with a default for invalid entries

            @param val <None/str> - The input value

            @param possibleValues list<str> - A list of possible values

            @param invalidDefault <None/str/Exception> - The value to return if "val" is not empty string/None
                                                           and "val" is not in #possibleValues

                     If instantiated Exception (like ValueError('blah')):  Raise this exception

                     If an Exception type ( like ValueError ) - Instantiate and raise this exception type

                     Otherwise, use this raw value

            @param emptyValue Default '', used for an empty value (empty string or None)

    '''
    from .utils import tostr

    # If null, retain null
    if val is None:
        if emptyValue is EMPTY_IS_INVALID:
            return _handleInvalid(invalidDefault)
        return emptyValue

    # Convert to a string
    val = tostr(val).lower()

    # If empty string, same as null
    if val == '':
        if emptyValue is EMPTY_IS_INVALID:
            return _handleInvalid(invalidDefault)
        return emptyValue

    # Check if this is a valid value
    if val not in possibleValues:
        return _handleInvalid(invalidDefault)

    return val


Instruction:
Explain what the following Python 3 code does
def convertToIntRange(val, minValue, maxValue, invalidDefault, emptyValue=''):
    '''
        converToIntRange - Convert input value to an integer within a certain range

            @param val <None/str/int/float> - The input value

            @param minValue <None/int> - The minimum value (inclusive), or None if no minimum

            @param maxValue <None/int> - The maximum value (inclusive), or None if no maximum

            @param invalidDefault <None/str/Exception> - The value to return if "val" is not empty string/None
                                                           and "val" is not in #possibleValues

                     If instantiated Exception (like ValueError('blah')):  Raise this exception

                     If an Exception type ( like ValueError ) - Instantiate and raise this exception type

                     Otherwise, use this raw value

            @param emptyValue Default '', used for an empty value (empty string or None)

    '''
    from .utils import tostr

    # If null, retain null
    if val is None or val == '':
        if emptyValue is EMPTY_IS_INVALID:
            return _handleInvalid(invalidDefault)
        return emptyValue

    try:
        val = int(val)
    except ValueError:
        return _handleInvalid(invalidDefault)

    if minValue is not None and val < minValue:
        return _handleInvalid(invalidDefault)
    if maxValue is not None and val > maxValue:
        return _handleInvalid(invalidDefault)

    return val

Response: Convert input value to an integer within a certain range.