trictionary?

mensanator at aol.com mensanator at aol.com
Tue Aug 30 01:32:40 EDT 2005


Bengt Richter wrote:
> On 28 Aug 2005 18:54:40 -0700, "mensanator at aol.com" <mensanator at aol.com> wrote:
>
> >Steven Bethard wrote:
> >> Adam Tomjack wrote:
> >> > Steven Bethard wrote:
> >> > ...
> >> >> Using a two element list to store a pair of counts has a bad code
> >> >> smell to me.
> >> > ...
> >> >
> >> > Why is that?
> >>
> >> Note that "code smell"[1] doesn't mean that something is actually wrong,
> >> just that it might be.  In Python, pairs are usually handled with
> >> tuples[2], but tuples would be inconvenient in this case, since the
> >> first value must be modified.  Declaring a class with two attributes as
> >> you suggested is often a good substitute, but if the OP's code is really
> >> what it looks like, I get another code smell because declaring a class
> >> to be used by only 10 lines of code seems like overkill.
> >>
> >> I also get a code smell from a dict holding two-element lists because
> >> I've been writing in Python and answering questions on the Python-list
> >> for a couple of years now, and I've never needed one yet. ;-)
> >>
> >> STeVe
> >>
> >> [1]http://en.wikipedia.org/wiki/Code_smell
> >> [2]http://www.python.org/doc/faq/general.html#why-are-there-separate-tuple-and-list-data-types
> >
> >Could you do me a favor and see what this smells like?
> >
> >I put some data in a csv file (with headers) and this will
> >bring it in quite simply as a dictionary with [names] as
> >keys and an attribute dictionary as the value.
> >
> >py_monsters.csv:
> >
> >name,hardiness,agility,friend,courage,room,weight,special_def_odds,armor,weapon,odds,dice,side,hits,reaction,desc
> >PIRATE,5,20,0,10,26,300,0,0,11,60,1,10,0,"not met",You see a man with a
> >beard and a brass ring in his ear.  He is wearing clothes  made of silk
> >and is wielding a very fancily engraved sword.
> >
> >
> >import csv
> >temp1 = []
> >temp2 = []
> >reader = csv.reader(file(r"py_monsters.csv"))
> >for rec in reader:
> >	temp1.append(rec)
> >for i in temp1[1:]:
> >	temp2.append((i[0],dict(zip(temp1[0][1:],i[1:]))))
> >monsters = dict(temp2)
> >
> >This gives me what I want
> >
> >[('PIRATE', {'reaction': 'not met',
> >'agility': '20',
> >'room': '26',
> >'weight': '300',
> >'armor': '0',
> >'weapon': '11',
> >'hits': '0',
> >'side': '10',
> >'special_def_odds': '0',
> >'courage': '10',
> >'hardiness': '5',
> >'desc': 'You see a man with a beard and a brass ring in his ear.
> >He is wearing clothes  made of silk and is wielding a very fancily
> >engraved sword.',
> >'odds': '60',
> >'friend': '0',
> >'dice': '1'})]
> >
> >so that I can now write code like
> >
> >if monsters['PIRATE']['reaction']=='not met':
> >        print monsters['PIRATE']['desc']
>
> I think if the field names are legal python names, I would rather write that 'if ...'
> without all that line noise ;-) E.g., using simple classes (and effectively using
> their attribute instance dicts essentially the way you used raw dicts), you could write
>
>     if monsters.PIRATE.reaction == 'not met':
>         print monsters.PIRATE.desc
>
> Also, if the reaction, agility, etc list is fixed, you could use __slots__ for
> better efficiency. Also, your __init__ method for the latter could convert
> strings to ints for handier use later (unless csv already does that in the mode
> you are using).

No, it doesn't as I found out shortly after posting that. What was I
thinking?
I've got it fixed for the moment, but that idea of classes sounds
interesting.

>
> From the above code I infer that you can do define the requisite classes, so
> I'll leave it to you ;-)

Guess I'll have to actually start reading the manuals.

> Note that attribute access opens the door to having
> default values as class variables, and using properties to retrieve dynamically
> calculated values by name. If you are not familiar with those aspects of classes,
> your progammer.agility value can increase markedly with a little study ;-)
>
> E.g., a name like monsters.random_elf could live right
> alongside PIRATE and return one a randomly selected elf from a an internal list
> of elves or via random selection from a list of elf names defined at the same
> level as PIRATE, etc. etc. You could also dynamically configure these guys
> according to distance to food and time since last meal, and if you are
> carrying food, etc.
>
> With suitable classes you could put instances in various "spaces" defined
> by other classes, that define geometric or social or other interactions.

Well, this is a port of The Wonderful World of Eamon, which isn't quite
that ambitious,
but thanks for the idea about classes. It's one of those many things I
just skim past
without ever understanding. Now would be a good time to start learning
it.

>
> >
> >instead of using stupid index numbers.
> >
> >But the loader seems to have a kind of perl-like odor to it,
> >i.e., next week I won't understand what it does.
> >
> If you have to do something tricky, choose names wisely and
> comment the non-obvious ;-)
> 
> Regards,
> Bengt Richter




More information about the Python-list mailing list