<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def compare(localtopdir, jottamountpoint, JFS, followlinks=False, exclude_patterns=None):
 """Make a tree of local files and folders and compare it with what's currently on JottaCloud. For each folder, yields: dirpath, # byte string, full path onlylocal, # set(), files that only exist locally, i.e. newly added files that don't exist online, onlyremote, # set(), files that only exist in the JottaCloud, i.e. deleted locally bothplaces # set(), files that exist both locally and remotely onlyremotefolders, # set(), folders that only exist in the JottaCloud, i.e. deleted locally """

    def excluded(unicodepath, fname):
        fpath = os.path.join(unicodepath, _decode_filename_to_unicode(fname))
        # skip FIFOs, block devices, character devices and the like, see bug#129
        mode = os.stat(fpath).st_mode
        if not (stat.S_ISREG(mode) or 
                stat.S_ISLNK(mode) or
                stat.S_ISDIR(mode)): # we only like regular files, dirs or symlinks
            return True
        if exclude_patterns is None:
            return False
        for p in exclude_patterns:
            if p.search(fpath):
                log.debug("%r excluded by pattern %r", fpath, p.pattern)
                return True
        return False
    bytestring_localtopdir = _encode_filename_to_filesystem(localtopdir)
    for dirpath, dirnames, filenames in os.walk(bytestring_localtopdir, followlinks=followlinks):
        # to keep things explicit, and avoid encoding/decoding issues,
        # keep a bytestring AND a unicode variant of dirpath
        dirpath = _encode_filename_to_filesystem(dirpath)
        unicodepath = _decode_filename_to_unicode(dirpath)
        log.debug("compare walk: %r -> %s files ", unicodepath, len(filenames))

        # create set()s of local files and folders
        # paths will be unicode strings
        localfiles = set([f for f in filenames if not excluded(unicodepath, f)]) # these are on local disk
        localfolders = set([f for f in dirnames if not excluded(unicodepath, f)]) # these are on local disk
        jottapath = get_jottapath(localtopdir, unicodepath, jottamountpoint) # translate to jottapath
        log.debug("compare jottapath: %r", jottapath)

        # create set()s of remote files and folders
        # paths will be unicode strings
        cloudfiles = filelist(jottapath, JFS) # set(). these are on jottacloud
        cloudfolders = folderlist(jottapath, JFS)

        log.debug("--cloudfiles: %r", cloudfiles)
        log.debug("--localfiles: %r", localfiles)
        log.debug("--cloudfolders: %r", cloudfolders)

        onlylocal = [ sf(f, dirpath, jottapath) for f in localfiles.difference(cloudfiles)]
        onlyremote = [ sf(f, dirpath, jottapath) for f in cloudfiles.difference(localfiles)]
        bothplaces = [ sf(f, dirpath, jottapath) for f in localfiles.intersection(cloudfiles)]
        onlyremotefolders = [ sf(f, dirpath, jottapath) for f in cloudfolders.difference(localfolders)]
        yield dirpath, onlylocal, onlyremote, bothplaces, onlyremotefolders