A question of style (finding item in list of tuples)

2012-05-21 Thread Roy Smith
I've got this code in a django app:

CHOICES = [
('NONE', 'No experience required'),
('SAIL', 'Sailing experience, new to racing'),
('RACE', 'General racing experience'),
('GOOD', 'Experienced racer'),
('ROCK', 'Rock star'),
]

def experience_text(self):
for code, text in self.CHOICES:
if code == self.level:
return text
return 

Calling experience_text(ROCK) should return Rock star.  Annoyingly, 
django handles this for you automatically inside a form, but if you also 
need it in your application code, you have to roll your own.

The above code works, but it occurs to me that I could use the much 
shorter:

def experience_text(self):
return dict(CHOICES).get(self.level, ???)

So, the question is, purely as a matter of readability, which would you 
find easier to understand when reading some new code?  Assume the list 
of choices is short enough that the cost of building a temporary dict on 
each call is negligible.  I'm just after style and readability here.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A question of style (finding item in list of tuples)

2012-05-21 Thread Chris Angelico
On Mon, May 21, 2012 at 10:37 PM, Roy Smith r...@panix.com wrote:
 The above code works, but it occurs to me that I could use the much
 shorter:

    def experience_text(self):
        return dict(CHOICES).get(self.level, ???)

 So, the question is, purely as a matter of readability, which would you
 find easier to understand when reading some new code?  Assume the list
 of choices is short enough that the cost of building a temporary dict on
 each call is negligible.  I'm just after style and readability here.

Is there a reason not to keep the dictionary around? That would surely
be the most logical thing to do. (With, of course, no quotes around
self.level.)

But out of your two options, I'd go with the loop. It's clear what
you're doing and doesn't fiddle around with multiple translations.

Chris Angelico
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A question of style (finding item in list of tuples)

2012-05-21 Thread Steven D'Aprano
On Mon, 21 May 2012 08:37:29 -0400, Roy Smith wrote:

[...]
 The above code works, but it occurs to me that I could use the much
 shorter:
 
 def experience_text(self):
 return dict(CHOICES).get(self.level, ???)
 
 So, the question is, purely as a matter of readability, which would you
 find easier to understand when reading some new code?

Definitely the dictionary lookup.

Rather than convert list CHOICES to a dict every time, you might convert 
it to a dict *once*, then just write:

return CHOICES.get(self.level, ???)

 Assume the list
 of choices is short enough that the cost of building a temporary dict on
 each call is negligible.

Negligible or not, why bother?

Not that it really matters -- if you have a good reason for CHOICES to 
remain a list, still stick with the dict lookup rather than a explicit 
loop.


-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A question of style (finding item in list of tuples)

2012-05-21 Thread David Lambert

One suggestion is to construct the dictionary first:


CHOICES = dict(
NONE = 'No experience required',
SAIL = 'Sailing experience, new to racing',
RACE = 'General racing experience',
GOOD = 'Experienced racer',
ROCK = 'Rock star'
)

def experience_text(self):
try:
return CHOICES[self]
except:
return 



On 05/21/2012 07:37 AM, Roy Smith wrote:

I've got this code in a django app:

 CHOICES = [
 ('NONE', 'No experience required'),
 ('SAIL', 'Sailing experience, new to racing'),
 ('RACE', 'General racing experience'),
 ('GOOD', 'Experienced racer'),
 ('ROCK', 'Rock star'),
 ]

 def experience_text(self):
 for code, text in self.CHOICES:
 if code == self.level:
 return text
 return 

Calling experience_text(ROCK) should return Rock star.  Annoyingly,
django handles this for you automatically inside a form, but if you also
need it in your application code, you have to roll your own.

The above code works, but it occurs to me that I could use the much
shorter:

 def experience_text(self):
 return dict(CHOICES).get(self.level, ???)

So, the question is, purely as a matter of readability, which would you
find easier to understand when reading some new code?  Assume the list
of choices is short enough that the cost of building a temporary dict on
each call is negligible.  I'm just after style and readability here.


--
http://mail.python.org/mailman/listinfo/python-list


Re: A question of style (finding item in list of tuples)

2012-05-21 Thread Tim Chase
On 05/21/12 08:10, Steven D'Aprano wrote:
 On Mon, 21 May 2012 08:37:29 -0400, Roy Smith wrote:
 
 [...]
 The above code works, but it occurs to me that I could use the much
 shorter:

 def experience_text(self):
 return dict(CHOICES).get(self.level, ???)

 So, the question is, purely as a matter of readability, which would you
 find easier to understand when reading some new code?
 
 Definitely the dictionary lookup.
 
 Rather than convert list CHOICES to a dict every time, you might convert 
 it to a dict *once*, then just write:
 
 return CHOICES.get(self.level, ???)

While I back Steven's suggestion, I'd keep *both* around.  The
dictionary isn't inherently ordered, so presenting it to the user
may come out with a differing orders depending on how code gets hit.
 So I'd do

  CHOICES = [
(NONE, No experience required),
...
]
  CHOICE_DICT = dict(CHOICES)

once at setup, and then use Steven's suggestion of

  return CHOICES_DICT.get(self.level, ???)

then you get the best of both worlds:  You can specify the order for
presentation using CHOICES, and get O(1) lookups and defaulting via
CHOICE_DICT.

-tkc



-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A question of style (finding item in list of tuples)

2012-05-21 Thread Jon Clements
On Monday, 21 May 2012 13:37:29 UTC+1, Roy Smith  wrote:
 I've got this code in a django app:
 
 CHOICES = [
 ('NONE', 'No experience required'),
 ('SAIL', 'Sailing experience, new to racing'),
 ('RACE', 'General racing experience'),
 ('GOOD', 'Experienced racer'),
 ('ROCK', 'Rock star'),
 ]
 
 def experience_text(self):
 for code, text in self.CHOICES:
 if code == self.level:
 return text
 return 
 
 Calling experience_text(ROCK) should return Rock star.  Annoyingly, 
 django handles this for you automatically inside a form, but if you also 
 need it in your application code, you have to roll your own.
 
 The above code works, but it occurs to me that I could use the much 
 shorter:
 
 def experience_text(self):
 return dict(CHOICES).get(self.level, ???)
 
 So, the question is, purely as a matter of readability, which would you 
 find easier to understand when reading some new code?  Assume the list 
 of choices is short enough that the cost of building a temporary dict on 
 each call is negligible.  I'm just after style and readability here.

Haven't used django in a while, but doesn't the model provide a 
get_experience_display() method which you could use...

Failing that, if order isn't important, you can not bother with tuples and have 
CHOICES be a dict, then pass choices=CHOICES.iteritems() as I believe it takes 
any iterable, and maybe plug an ordereddict if order is important.

hth

Jon.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A question of style (finding item in list of tuples)

2012-05-21 Thread Roy Smith
On Monday, May 21, 2012 9:39:59 AM UTC-4, Jon Clements wrote:

  def experience_text(self):
  return dict(CHOICES).get(self.level, ???)

 Haven't used django in a while, but doesn't the model provide a 
 get_experience_display() method which you could use...

Duh, I totally missed seeing that!  Yeah, that's exactly what I want.  Thanks.  
Hmmm, looking at the source, I see they went the dict().get() route:

def _get_FIELD_display(self, field):
value = getattr(self, field.attname)
return force_unicode(dict(field.flatchoices).get(value, value), 
strings_only=True)
-- 
http://mail.python.org/mailman/listinfo/python-list