Poweruser32
Poweruser32

Reputation: 5

Creating a set from a variable instead of a file

I have a piece of code to read two files, convert them to sets, and then subtract one set from the other. I would like to use a string variable (installedPackages) for "a" instead of a file. I would also like to write to a variable for "c".

a = open("/home/user/packages1.txt")
b = open("/home/user/packages.txt")
c = open("/home/user/unique.txt", "w")

for line in set(a) - set(b):
    c.write(line)

a.close()
b.close()
c.close()

I have tried the following and it does not work:

for line in set(installedPackages) - set(b):

I have tried to use StringIO, but I think I am using it improperly.

Here, finally, is how I have created installedPackages:

stdout, stderr = p.communicate()
installedPackages = re.sub('\n$', '', re.sub('install$', '', re.sub('\t', '', stdout), 0,re.MULTILINE))

Sample of packages.txt:

humanity-icon-theme
hunspell-en-us
hwdata
hyphen-en-us
ibus
ibus-gtk
ibus-gtk3
ibus-pinyin
ibus-pinyin-db-android
ibus-table

Upvotes: 0

Views: 93

Answers (3)

Hugh Bothwell
Hugh Bothwell

Reputation: 56674

Something like the following?

Edit: after several iterations:

from subprocess import Popen, PIPE

DEBUG = True
if DEBUG:
    def log(msg, data):
        print(msg)
        print(repr(data))
else:
    def log(msg, data):
        pass

def setFromFile(fname):
    with open(fname) as inf:
        return set(ln.strip() for ln in inf)

def setFromString(s):
    return set(ln.strip() for ln in s.split("\n"))

def main():
    # get list of installed packages
    p = Popen(['dpkg', '--get-selections'], stdout=PIPE, stderr=PIPE)
    stdout, stderr = p.communicate()
    installed_packages = setFromString(stdout)

    # get list of expected packages
    known_packages = setFromFile('/home/john/packages.txt')

    # calculate the difference
    unknown_packages = installed_packages - known_packages
    unknown_packages_string = "\n".join(unknown_packages)

    log("Installed packages:", installed_packages)
    log("Known packages:", known_packages)
    log("Unknown packages:", unknown_packages)

if __name__=="__main__":
    main()

Upvotes: 1

garnertb
garnertb

Reputation: 9594

The set data type takes an iterable as a parameter, therefore if installedPackages a string with multiple items you need to split it by the delimiter. For example, the following code would split the string by all commas:

for line in set(installedPackages.split(',')) - set(b):
    c.write(line)

Upvotes: 1

jamylak
jamylak

Reputation: 133634

If you want to write to a string buffer file-like use StringIO

>>> from StringIO import StringIO
>>> installed_packages = StringIO()
>>> installed_packages.write('test')
>>> installed_packages.getvalue()
'test'

Upvotes: 2

Related Questions