Home     |     .Net Programming    |     cSharp Home    |     Sql Server Home    |     Javascript / Client Side Development     |     Ajax Programming

Ruby on Rails Development     |     Perl Programming     |     C Programming Language     |     C++ Programming     |     IT Jobs

Python Programming Language     |     Laptop Suggestions?    |     TCL Scripting     |     Fortran Programming     |     Scheme Programming Language


 
 
Cervo Technologies
The Right Source to Outsource

MS Dynamics CRM 3.0

Python Programming Language

*Naming Conventions*


Okay,

I hear you saying 'not another naming conventions thread'. I've read
through Google and the 'naming conventions' threads were rather
*spelling conventions* threads.

I'm not interested in camelCase versus camel_case or anything
mentioned in  'PEP 8 -- Style Guide for Python Code'. What I'm looking
for is hints or ideas how to name your variables and especially how to
name functions, methods and classes.

I know this depends on what the function is doing. If I know what it
is doing I should be able to give them a desciptive name. But actually
I'm often not able. Especially when the task is quite similar to
another function or Class.

Recently I wrote this code and noticed that I was completely lost in
giving these objects names to describe and distinguish them:

for validanswer in validanswers:
    if myAnswers.myanswer in myAnswers.validAnswers[validanswer]:
        MyOptions['style'] = validanswer

The 'tips' I got through some postings or articles on the net are: if
a function simply tests something and returns a boolean call it

def is_<whatever_you_are_testing_for>():
 pass

like 'is_even'.

Makes sense. The other thing I captured was to use something like

def get_values():

... Makes sense, too, but aren't all functions getting something?

So if someone had a similar dilemma to mine and could tell me how he
dealt with that, I'd be grateful...

Thorsten

In <MPG.20cd2ef21ffc1137989@news.individual.de>, Thorsten Kampe wrote:

> Recently I wrote this code and noticed that I was completely lost in
> giving these objects names to describe and distinguish them:

> for validanswer in validanswers:
>     if myAnswers.myanswer in myAnswers.validAnswers[validanswer]:
>         MyOptions['style'] = validanswer

Wow, I know you don't want to talk about "spelling conventions" but here
you are mixing many of them.  :-)

I don't know if it makes sense for your code, but maybe you can move the
``if`` condition into the class of `myAnswer` as overloaded ``in``
operator.  Then this can be written as:

for valid_answer in valid_answers:
    if valid_answer in my_answers:
        my_options['style'] = valid_answer

> The 'tips' I got through some postings or articles on the net are: if
> a function simply tests something and returns a boolean call it

> def is_<whatever_you_are_testing_for>():
>  pass

The other typical boolean test prefix is 'has_'.

> like 'is_even'.

> Makes sense. The other thing I captured was to use something like

> def get_values():

> ... Makes sense, too, but aren't all functions getting something?

So you may reduce this to just `values()`.  On the other hand there is the
convention to name functions and methods as verbs that are "doing"
something.

Ciao,
        Marc 'BlackJack' Rintsch

--- Thorsten Kampe <thors@thorstenkampe.de> wrote:

> for validanswer in validanswers:
>     if myAnswers.myanswer in
> myAnswers.validAnswers[validanswer]:
>         MyOptions['style'] = validanswer

I can at least sympathize with your problem, although
I don't have a great solution for you.  I often have
trios of variables like this:

   answer_dct
   answers
   answer

English mostly pluralizes with an "s," but I sometimes
resort to bad English to keep the convention going:

   mouse_dct
   mouses (not mice)
   mouse

I also still waste brain cycles on naming
dictionaries.  Sometimes I name the dictionary after
the values it stores, sometimes after the keys it
uses, and sometimes after both.

      ___________________________________________________________________________ _________
Luggage? GPS? Comic books?
Check out fitting gifts for grads at Yahoo! Search
http://search.yahoo.com/search?fr=oni_on_mail&p=graduation+gifts&cs=bz

On Jun 4, 5:03 am, Thorsten Kampe <thors@thorstenkampe.de> wrote:

> for validanswer in validanswers:
>     if myAnswers.myanswer in myAnswers.validAnswers[validanswer]:
>         MyOptions['style'] = validanswer

First, for small loops with loop variables whose meaning is obvious
from context, the most readable name is usually something like 'i' or
'j'. It avoids unnecessary duplication and clutter. Of course, just as
physically turning your head to look in the rear view mirror is
necessary in a driving test but stupid for real driving, you are
likely to be penalised for this if you do it in an educational setting
or somewhere else where daft coding conventions are strictly enforced
(I once worked in a company that had library constants 'Zero' and
'One' defined because the coding conventions insisted on absolutely no
unnamed 'magic numbers' - spelling the numbers using letters
apparently didn't count).

Second, when naming a member, you should take into account that
references will already be specifying what the whole class describes.
That is, provide new information where possible, and avoid unnecessary
repetition.

Since Python is dynamically typed, it can be useful for names to
describe the datatype of the content at times (though not to the
Hungarian notation extreme that is common is C code, esp. for
Windows). And while most variable names are nouns, sometimes
adjectives are most appropriate - esp where the noun is already clear
from context.

Based on this, your code might become something like...

  for i in validanswers:
    if myAnswers.current in myAnswers.validList [i]:
      MyOptions['style'] = i

  'i'
      Its obviously a validanswer since it is one of
      the validanswers.

  'myAnswers.current'
      I know its related to myAnswers, but the
      adjective 'current' tells me more about this
      specific member.

  'myAnswers.validList'
      'valid' on its own is useful extra information,
      but suggests a flag field. validList is better
      since it avoids that confusion.

Depending on what myAnswers.myanswer actually holds, it might
alternately be renamed something like myAnswers.uid or myAnswers.id (a
[unique] identifier code identifying the answer) or myAnswers.text
(the text of the answer).

It is also often useful to use a convention where a prefix identifies
whether a name is a (p)arameter, (l)ocal variable, or (m)ember
variable - no prefix for functions, usually. For example, a simple
setter method may logically use the same name for the parameter
specifying the value to write, the member variable to write to, and
(barring a prefix along the lines of 'Set') the method name.

On Jun 3, 4:32 pm, Steve Howell <showel@yahoo.com> wrote:

> I also still waste brain cycles on naming
> dictionaries.  Sometimes I name the dictionary after
> the values it stores, sometimes after the keys it
> uses, and sometimes after both.

I was in the same boat but now I've pretty much settled to the
convention `key2value`, e.g.:

name2func = {
  'sum'     : sum,
  'avg'     : lambda values: sum(values) / float(len(values))
  'product' : lambda values: reduce(operator.mul,values,1),

}

word2positions = {
  'dog' : [3, 45, 79, 840],
  'cat' : [56, 97, 810],

}

At some point I was torn between this and the plural form, i.e.
`keys2values`, but that's ambiguous in cases where each key or value
is a collection, such as the 'positions' above.

While we're at it, although it's not strictly a naming convention
issue I still waste brain cycles on where to put the import statements
that are used only once or twice in a module. Should
(1) all imports be at the global scope at the top of the module, or
(2) be imported in the function or method they are actually used ?

Reasons for (1)
---------------
- PEP-8 compatible.
- Easy to see all external dependencies in one place.

Reasons for (2)
---------------
- Point of import closer to point of use; easy to notice if a given
import is not used any more after refactoring.
- Less name pollution.
- Faster name lookup in locals (might make a difference for tight
loops).

I usually go for (1), at least until the number of global imports in
the top remains in single digits. After some point though I often
localize the standard library imports that are used only once or twice
(the third-party and local application imports are almost always
global). Any others that are not strictly PEP-8 compliant on this ?

George

On Jun 3, 11:03 pm, Thorsten Kampe <thors@thorstenkampe.de> wrote:

> Okay,

> I hear you saying 'not another naming conventions thread'. I've read
> through Google and the 'naming conventions' threads were rather
> *spelling conventions* threads.

> I'm not interested in camelCase versus camel_case or anything
> mentioned in  'PEP 8 -- Style Guide for Python Code'. What I'm looking
> for is hints or ideas how to name your variables and especially how to
> name functions, methods and classes.

In my code:

* The most common form of a function/method name is verb_noun.  Other
common patterns are adjective_noun, noun_to_noun or noun2noun (for
conversions), and noun_of_noun.

* Classes nearly always have AdjectiveNoun names.

* Loop indices often have single-letter names (typically i/j/k or x/
y), or names that are the singular form of the list name (e.g., "for
ballot in self._ballots").  For iterating over files, I use "line".

--- Dan Bishop <danb@yahoo.com> wrote:

> * Loop indices often have single-letter names
> (typically i/j/k or x/
> y), or names that are the singular form of the list
> name (e.g., "for
> ballot in self._ballots").  For iterating over
> files, I use "line".

You are in good company with "i" and "line."  They are
among the 15 most used tokens in the Python standard
library, which includes reserved words if, def,
return, in, not, else, and for.

16610 self
7347 if
5222 def
4686 return
2818 None
2235 in
1799 not
1723 else
1637 name
1499 i
1226 os
1224 line
1203 for
1183 data
1181 path

I sampled /usr/local/lib/python2.5 with tokenizer.

___________________________________________________________________________ _________
Got a little couch potato?
Check out fun summer activities for kids.
http://search.yahoo.com/search?fr=oni_on_mail&p=summer+activities+for...

Thorsten Kampe wrote:
> for validanswer in validanswers:
>     if myAnswers.myanswer in myAnswers.validAnswers[validanswer]:
>         MyOptions['style'] = validanswer

I usually try to avoid using "my" because I find it obscures a better
understanding of what is really going

--
Michael Hoffman

Michael Hoffman wrote:
> Thorsten Kampe wrote:

>> for validanswer in validanswers:
>>     if myAnswers.myanswer in myAnswers.validAnswers[validanswer]:
>>         MyOptions['style'] = validanswer

> I usually try to avoid using "my" because I find it obscures a better
> understanding of what is really going

...on.

Whoops, sorry about missing the last word of that message.
--
Michael Hoffman

In <1180911610.702985.215@q75g2000hsh.googlegroups.com>, George Sakkis
wrote:

> While we're at it, although it's not strictly a naming convention
> issue I still waste brain cycles on where to put the import statements
> that are used only once or twice in a module. Should
> (1) all imports be at the global scope at the top of the module, or
> (2) be imported in the function or method they are actually used ?

> []

> Reasons for (2)
> ---------------
> - Point of import closer to point of use; easy to notice if a given
> import is not used any more after refactoring.

`pylint` reports unused imported names.  I don't follow PEP8 only if it's
not possible otherwise.  But cyclic imports are bad anyway.  :-)

And if the import is *really* expensive and only needed in some special
circumstances.

Ciao,
        Marc 'BlackJack' Rintsch

On Jun 4, 12:20 am, Ninereeds <stephenhorne@aol.com> wrote:

> On Jun 4, 5:03 am, Thorsten Kampe <thors@thorstenkampe.de> wrote:

> > for validanswer in validanswers:
> >     if myAnswers.myanswer in myAnswers.validAnswers[validanswer]:
> >         MyOptions['style'] = validanswer

> First, for small loops with loop variables whose meaning is obvious
> from context, the most readable name is usually something like 'i' or
> 'j'.

'i' and 'j' are the canonical names for for loops indices in languages
that don't support proper iteration over a sequence. Using them for
the iteration variable of a Python for loop (which is really a
'foreach' loop) would be at best confusing.

(snip)

> Based on this, your code might become something like...

>   for i in validanswers:
>     if myAnswers.current in myAnswers.validList [i]:
>       MyOptions['style'] = i

And this is *exactly* what one should not do in Python. If you want a
generic name here, use 'item' instead.

> It is also often useful to use a convention where a prefix identifies
> whether a name is a (p)arameter, (l)ocal variable, or (m)ember

You don't have to use any kind of prefix for attributes ('member' is
not a Python idiom - remember that in Python, a method is also an
attribute...) since the use of 'self' is mandatoy.

And you usually don't need to distinguish 'local' from 'parameters',
since
1/ parameters names *are* local
2/ pythonic methods and functions tends to be short, so you usually
know which names are params.

FWIW, prefixing names this way is something I've almost never seen in
Python code.

> variable - no prefix for functions, usually. For example, a simple
> setter method

Python has a pretty good support for computed attributes (look for
'property'), so you don't need explicit getters/setters.

bruno.desthuilli@gmail.com wrote:
> On Jun 4, 12:20 am, Ninereeds <stephenhorne@aol.com> wrote:

>> First, for small loops with loop variables whose meaning is obvious
>> from context, the most readable name is usually something like 'i' or
>> 'j'.

> 'i' and 'j' are the canonical names for for loops indices in languages
> that don't support proper iteration over a sequence. Using them for
> the iteration variable of a Python for loop (which is really a
> 'foreach' loop) would be at best confusing.

While that is true, I guess it is commonplace to use i, j, k and n
(maybe others) in constructs like

for i in range(len(data)):
    do_stuff(data[i])

Or should the good python hacker do that differently? Hope not ;).

/W

Well, yes, I would do:

for item in data:
    do_stuff(item)

or, if using enumerate:

for item_index, item in enumerate(data):
    do_stuff(item_index, item)

I agree with Bruno that i and j should be used only for indices, but I'm
usually less terse than that.
--
Michael Hoffman

On Mon, 2007-06-04 at 23:20 +0200, Wildemar Wildenburger wrote:
>  I guess it is commonplace to use i, j, k and n
> (maybe others) in constructs like

> for i in range(len(data)):
>     do_stuff(data[i])

> Or should the good python hacker do that differently? Hope not ;).

That's a big, fat "Heck, Yes":

for thing in data:
   do_stuff(thing)

--
Carsten Haese
http://informixdb.sourceforge.net

Boy is my face red! Holy Moly ... that was so obvious! See, that's what
you get for coding too much matlab! Screw that!

/W

On 2007-06-04, Michael Hoffman <cam.ac@mh391.invalid> wrote:

I find i and j preferable to overly generic terms like "item."

--
Neil Cerutti

Neil Cerutti wrote:
> I find i and j preferable to overly generic terms like "item."

Well, I probably wouldn't use "item" in a real example, unless it were
for a truly generic function designed to act on all sequences.
--
Michael Hoffman
Google Groups appears to have thrown away my original reply, so sorry
if this appears twice...

On Jun 4, 9:51 pm, "bruno.desthuilli@gmail.com"

<bruno.desthuilli@gmail.com> wrote:
> 'i' and 'j' are the canonical names for for loops indices in languages
> that don't support proper iteration over a sequence. Using them for
> the iteration variable of a Python for loop (which is really a
> 'foreach' loop) would be at best confusing.

Without wanting to start a religious war, I disagree.

In practice, I believe most programmers associate those short names
with pretty much any loop

variable, irrespective of data type, based primarily on the simple
fact that it's looping

over a set of values whose meaning is obvious from context. That
declaration is made after

decades of working with other peoples code as well as my own.

Don't believe me? Take a look at some code that uses C++ iterators,
for example, or some C

code that uses pointers as iterators, or some Ada code that loops over
an enumerated type,

etc etc. It won't find you long to realise that 'i' and 'j' are very
common names for those

too.

I've seen 'i' used in "iterations" over lists in Scheme, OCaml and
Haskell, whether done

using tail recursion or list comprehensions or whatever. 'x' is more
common, as with 'x:xs'

patterns used to pick the head 'x' from a list in OCaml or Haskell,
but then 'x' looks

scarily like an ordinate we can't have that ;-)

Anyway, why should 'indexes' always be numeric...

> >   for i in validanswers:
> >     if myAnswers.current in myAnswers.validList [i]:
> >       MyOptions['style'] = i

> And this is *exactly* what one should not do in Python. If you want a
> generic name here, use 'item' instead.

In this code, 'i' is appears to be just an answer identifier. It is
used to identify for

which answer in the validList you are looking for. It may well even be
a numeric index (or

some other kind of key), from what we can see in the example.

"item" says nothing that "i" does not. If nothing else, you could
always say that 'i' is

short for 'item' or 'id' or whatever.

> since the use of 'self' is mandatoy.

That is true, making 'm' prefixes pointless in Python, but that's what
comes from working

with many different language. You don't always keep them neatly
compartmentalised in your

head. Habits can be very strong, and there is not always any strong
reason to try to break

them. Which is why you will still occasionally see 'm' prefixes in
Python code.

Actually, in *my* Python code you're still more likely to see
'f' (standing for field)

prefixes - a convention I adopted in C++ at a time when I thought 'm'
better suited macros,

and when I'd never yet seen the 'm' for member prefix since most C++
code I'd seen still used

the Hungarian conventions. It's a bad habit that I still haven't fully
broken.

> 1/ parameters names *are* local

As they are in C and C++. Not just in terms of scoping, but in terms
of being local variables

too...

  int factorial (int p)
  {
    int l = 1;
    while (p > 1)  {  l *= p;  p--;  }
    return l;
  }

  def factorial (p) :
    l = 1
    while p > 1 : l *= p; p -= 1
    return l

Updating parameters when you could just as easily update locals is of
course bad style in

either language - and some would say that any updating of parameters
is bad style - but the

point is that C and Python do the same thing.

This example does illustrate another useful fact about the 'l' and 'p'
prefixes - there are

times when the prefix is all you need to specify the whole name, since
there really is

nothing else that can be usefully be said.

> 2/ pythonic methods and functions tends to be short, so you usually
> know which names are params.

Well written functions and methods in any language tend to be short,
but even so, there are

times when a convention that distinguishes the two kinds of names
without needing to think up

distinct names is convenient. I wasn't suggesting that this convention
should be universally

adopted in Python or that it was relevant to Thorstens example even -
but it is common in

many languages (not just C++), and it does sometimes help resolve the

how-can-I-give-these-meaningfully-different-names issue.

> Python has a pretty good support for computed attributes (look for
> 'property'), so you don't need explicit getters/setters.

I may not use Python as my first and only language, but I have been
using it since version

1.4 and I am perfectly aware of properties in Python, as I am in other
languages. I am aware,

for example, that they are relatively new additions to the language,
that they are not used

in a lot of code, and that you still need named getter and setter
functions to redirect the

property access to even if these names are only referred to in the
property definition.

All of which is mostly besides the point. More and more programmers
are multilingual these

days, and scripting languages such as Python are more likely second
languages than first.

Having a hard rule that conventions from one language should never
leak into another, and

that Python code should be somehow 'pure', is pointless, particularly
when those conventions

are common in many languages. Thorsten was having difficulty in
finding distinct names, and I

described a common naming convention that is often useful for this. I
don't think I was wrong

to do that.

Neil Cerutti a crit :

Since 'i' and 'j' are canonically loop indices, I find it totally
confusing to use them to name the iteration variable - which is not an
index. At least, 'item' suggests that it's an object, and a part of the
collection - not just an index you'll have to use to subscript the
container. Also, and as far as I'm concerned, I certainly dont find 'i'
and 'j' *less* generic than 'item' !-)

I agree that except for uber-generic code or quick throw-away script
'item' is probably not a very good name, but then nor are 'i' and 'j'...

Ninereeds a crit :

The fact that a bad practice is a common practice is by no mean an
excuse for promoting this bad practice.

FWIW, Python as a very strong philosophy when it comes to readability,
and I think it's the first time I see such a naming horror in Python.

> Anyway, why should 'indexes' always be numeric...

Because that's part of the commonly admitted definition in the context ?

In a dict, it's named a 'key', not an index. And the idiomatic shortcut
is 'k', not 'i'.

(snip)

>> since the use of 'self' is mandatoy.

> That is true, making 'm' prefixes pointless in Python, but that's what
> comes from working

> with many different language.

Ah, the good old 'I can write basic in any language' syndrom...

> You don't always keep them neatly
> compartmentalised in your

> head. Habits can be very strong, and there is not always any strong
> reason to try to break
> them.

I do not agree here, but that's another point. The problem is that you
are advertising a totally non-pythonic convention on c.l.py. Your post
will be archived for years, and some newbie may find it and follow your
bad advises. Please keep such advises for where they are appropriate.

> Which is why you will still occasionally see 'm' prefixes in
> Python code.

Never seen such a thing in 7 years of Python programming, and believe me
I've read a *lot* of Python code.

>> 1/ parameters names *are* local

> As they are in C and C++.

The relation between the name and the named object are somewhat
different in Python.

>> 2/ pythonic methods and functions tends to be short, so you usually
>> know which names are params.

> Well written functions and methods in any language tend to be short,

For a somewhat different definition of "short". A "short" C functions is
commonly tens of lines long - which, by Python standards, starts to
become a "too long" function.

>> Python has a pretty good support for computed attributes (look for
>> 'property'), so you don't need explicit getters/setters.

> I may not use Python as my first and only language, but I have been
> using it since version

> 1.4

Then you beat me !-)
(started with 1.5.2)

> and I am perfectly aware of properties in Python, as I am in other
> languages. I am aware,

> for example, that they are relatively new additions to the language,
> that they are not used

> in a lot of code, and that you still need named getter and setter
> functions to redirect the

> property access to even if these names are only referred to in the
> property definition.

class SomeClass(object):
   @apply
   def some_property():
     def fget(self):
       return self._somevalue
     def fset(self, newvalue):
       self._somevalue = newvalue
     return property(**locals())

Yes, true, the getter and the setter are named. But here, you don't even
have to worry a millisecond about how to name them.

> All of which is mostly besides the point. More and more programmers
> are multilingual these
> days,

So am I.

> and scripting languages such as Python are more likely second
> languages than first.

'second' by usage frequency or by learning order ?

> Having a hard rule that conventions from one language should never
> leak into another,

"never" ? Python stole almost anything - naming convention included -
from other languages. It's not a matter of "purity",  it's a matter of
filtering what makes sens and what doesn't.

> are common in many languages. Thorsten was having difficulty in
> finding distinct names, and I
> described a common naming convention that is often useful for this. I
> don't think I was wrong
> to do that.

See my comments above. If these conventions are totally alien to Python
(and have already been abandonned/rejected by people with similar
background as yours - strange enough, a lot of people here are C, C++ or
Java coders too), then as far as I'm concerned, yes, you are wrong to
advertise them here. Call me a purist if you want... (and please don't
take my remarks as a personal offense - it's just that I happen to be
have *very* strong opinions on some points).
On 2007-06-06, Bruno Desthuilliers

Thanks, I didn't say clearly what I meant.

Certainly i and j are just as generic, but they have the
advantage over 'item' of being more terse.

I'm in the habit of letting context indicates wether i is a
contained object or a subscript. The advantage of a terse,
one-letter name is how it draws attention to context, rather than
itself.

But it's a small distinction. I wouldn't call 'item' a bad
choice.

--
Neil Cerutti

Neil Cerutti a crit :

I'm not sure this is really an "advantage" here.
On 2007-06-08, Bruno Desthuilliers <bruno.42.desthuilli@wtf.websiteburo.oops.com> wrote:

Why not?

--
Neil Cerutti
Beethoven's symphonies had more balls, if you will, than say a Mozart. --Music
Lit Essay

Add to del.icio.us | Digg this | Stumble it | Powered by Megasolutions Inc