dictionary comparison
Bengt Richter
bokr at oz.net
Thu May 5 16:01:44 EDT 2005
On 5 May 2005 08:19:31 -0700, "rickle" <devrick88 at gmail.com> wrote:
>I'm trying to compare sun patch levels on a server to those of what sun
>is recommending. For those that aren't familiar with sun patch
>numbering here is a quick run down.
>
>A patch number shows up like this:
>113680-03
>^^^^^^ ^^
>patch# revision
>
>What I want to do is make a list. I want to show what server x has
>versus what sun recommends, and if the patch exists, but the revision
>is different, I want to show that difference.
>
>Here are some sample patches that sun recommends:
>117000-05
>116272-03
>116276-01
>116278-01
>116378-02
>116455-01
>116602-01
>116606-01
>
>Here are some sample patches that server x has:
>117000-01
>116272-02
>116272-01
>116602-02
>
>So there are some that are the same, some that sun recommends that
>server x doesn't have, and some where the patch is the same but the
>revision is different.
>
>I've thrown the data into dictionaries, but I just can't seem to figure
>out how I should actually compare the data and present it. Here's what
>I have so far (the split is in place because there is actually a lot
>more data in the file, so I split it out so I just get the patch number
>and revision). So I end up with (for example) 116272-01, then split so
>field[0] is 116272 and field[1] is 01.
>
>def sun():
> sun = open('sun-patchlist', 'r')
> for s in sun:
> sun_fields = s.split(None, 7)
> for sun_field in sun_fields:
> sun_field = sun_field.strip()
> sun_patch = {}
> sun_patch['number'] = sun_fields[0]
> sun_patch['rev'] = sun_fields[1]
> print sun_patch['number'], sun_patch['rev']
> sun.close()
>
>def serverx():
> serverx = open('serverx-patchlist', 'r')
> for p in serverx:
> serverx_fields = p.split(None, 7)
> for serverx_field in serverx_fields:
> serverx_field = serverx_field.strip()
> serverx_patch = {}
> serverx_patch['number'] = serverx_fields[0]
> serverx_patch['rev'] = serverx_fields[1]
> print serverx_patch['number'], serverx_patch['rev']
> serverx.close()
>
>if __name__=='__main__':
> sun()
> serverx()
>
>
>Right now I'm just printing the data, just to be sure that each
>dictionary contains the correct data, which it does. But now I need
>the comparison and I just can't seem to figure it out. I could
>probably write this in perl or a shell script, but I'm trying really
>hard to force myself to learn Python so I want this to be a python
>script, created with only built-in modules.
>
>Any help would be greatly appreciated,
>
In place of sun_rec.splitlines() and x_has.splitlines() you can substitute
open('sun-patchlist') adn open('serverx-patchlist') respectively,
and you can wrap it all in some rountine for your convenience etc.
But this shows recommended revs that are either there, missing, and/or have unrecommended revs present.
I added some test data to illustrate. You might want to make the input a little more forgiving about
e.g. blank lines etc or raise exceptions for what's not allowed or expected.
----< sunpatches.py >--------------------------------------------------------------
#Here are some sample patches that sun recommends:
sun_rec = """\
117000-05
116272-03
116276-01
116278-01
116378-02
116455-01
116602-01
116606-01
testok-01
testok-02
testok-03
test_0-01
test_0-02
test_0-03
test_2-01
test_2-02
test_2-03
test23-02
test23-03
"""
#Here are some sample patches that server x has:
x_has = """\
117000-01
116272-02
116272-01
116602-02
testok-01
testok-02
testok-03
test_2-01
test_2-02
test23-01
test23-02
test23-03
"""
def mkdict(lineseq):
dct = {}
for line in lineseq:
patch, rev = line.split('-')
dct.setdefault(patch, set()).add(rev)
return dct
dct_x_has = mkdict(x_has.splitlines()) # or e.g., mkdict(open('sunrecfile.txt'))
dct_sun_rec = mkdict(sun_rec.splitlines())
for sunpatch, sunrevs in sorted(dct_sun_rec.items()):
xrevs = dct_x_has.get(sunpatch, set())
print 'patch %s: recommended revs %s, missing %s, actual other %s'%(
sunpatch, map(str,sunrevs&xrevs) or '(none)',
map(str,sunrevs-xrevs) or '(none)', map(str,xrevs-sunrevs) or '(none)')
----------------------------------------------------------------------------------
Result:
[12:51] C:\pywk\clp>py24 sunpatches.py
patch 116272: recommended revs (none), missing ['03'], actual other ['02', '01']
patch 116276: recommended revs (none), missing ['01'], actual other (none)
patch 116278: recommended revs (none), missing ['01'], actual other (none)
patch 116378: recommended revs (none), missing ['02'], actual other (none)
patch 116455: recommended revs (none), missing ['01'], actual other (none)
patch 116602: recommended revs (none), missing ['01'], actual other ['02']
patch 116606: recommended revs (none), missing ['01'], actual other (none)
patch 117000: recommended revs (none), missing ['05'], actual other ['01']
patch test23: recommended revs ['02', '03'], missing (none), actual other ['01']
patch test_0: recommended revs (none), missing ['02', '03', '01'], actual other (none)
patch test_2: recommended revs ['02', '01'], missing ['03'], actual other (none)
patch testok: recommended revs ['02', '03', '01'], missing (none), actual other (none)
Oops, didn't pyt multiple revs in sort order. Oh well, you can do that if you like.
Regards,
Bengt Richter
More information about the Python-list
mailing list