[Tutor] Review and criticism of python project
Kent Johnson
kent37 at tds.net
Sat Jan 5 03:29:37 CET 2008
Tiger12506 wrote:
> Ouch. Usually in OOP, one never puts any user interaction into a class.
That seems a bit strongly put to me. Generally user interaction should
be separated from functional classes but you might have a class to help
with command line interaction (e.g. the cmd module in the std lib) and
GUI frameworks are usually built with classes.
>> uh, tf = line.split(',')
>> if uh in self.uhdata:
>> f=self.uhdata[uh]
>> if tf not in f:
>> f.append(tf)
>> else:
>> self.uhdata[uh]=[tf]
>
> This can read
>
> try:
> f = self.uhdata[uh]
> except KeyError:
> self.uhdata[uh] = []
> finally:
> self.uhdata[uh].append(tf)
These are not equivalent - the original code avoids duplicates in
self.uhdata[uh].
Possibly self.uhdata[uh] could be a set instead of a list. Then this
could be written very nicely using defaultdict:
from collections import defaultdict
...
self.uhdata = defaultdict(set)
...
self.uhdata[uh].add(tf)
>> for uh, Sections in self.uhdata.items():
>> Sections.sort()
>
> This will not work. In the documentation, it says that dictionary object
> return a *copy* of the (key,value) pairs.
> You are sorting those *copies*.
No, the original code is fine. The docs say that dict.items() returns "a
copy of a's list of (key, value) pairs". This is a little misleading,
perhaps. A dict does not actually contain a list of key, value pairs, it
is implemented with a hash table. dict.items() returns a new list
containing the key, value pairs.
But the keys and values in the new list are references to the same keys
and values in the dict. So mutating the values in the returned list, via
sort(), will also mutate the values in the dict.
>> missingpgcounts={}
>> fmissingpgcounts=[]
>> for x in self.uhdata:
>> for f in self.uhdata[x]:
>> if f not in fmissingpgcounts:
>> fmissingpgcounts.append(f)
>
> fmissingpgcounts = [f for f in self.uhdata.itervalues() if f not in
> fmissingpgcounts]
> Ahhh... This looks like a set.
> fmissingpgcounts = set(self.uhdata.itervalues())
Again, this is not quite the same thing. The original code builds a set
of the contents of the values. You are building a set from the values
(which are already lists). You still need one loop:
fmissingpgcounts = set()
for v in self.uhdate.itervalues():
fmissingpgcounts.update(v)
> self.pgcounts = dict((x,0) for x in fmissingpgcounts)
or, self.pgcounts = dict.fromkeys(fmissingpgcounts, 0)
That's all I have energy for...
Kent
More information about the Tutor
mailing list