*Naming Conventions*

  • Thread starter Marc 'BlackJack' Rintsch
  • Start date
M

Marc 'BlackJack' Rintsch

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
 
N

Ninereeds

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 :
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.
 
G

George Sakkis

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
 
D

Dan Bishop

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".
 
M

Michael Hoffman

Thorsten said:
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
 
M

Michael Hoffman

Michael said:
Thorsten said:
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.
 
T

Thorsten Kampe

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
 
M

Marc 'BlackJack' Rintsch

George Sakkis said:
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)

`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
 
B

bruno.desthuilliers

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 :
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.
 
W

Wildemar Wildenburger

'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)

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

/W
 
M

Michael Hoffman

Wildemar said:
'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)

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


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.
 
C

Carsten Haese

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)

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)
 
W

Wildemar Wildenburger

Carsten said:
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)

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)

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
 
N

Neil Cerutti

Wildemar said:
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)

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


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.


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

Michael Hoffman

Neil said:
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.
 
N

Ninereeds

Google Groups appears to have thrown away my original reply, so sorry
if this appears twice...

'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 :
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.
 
B

Bruno Desthuilliers

Neil Cerutti a écrit :
Wildemar said:
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)

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

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.


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


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'...
 
B

Bruno Desthuilliers

Ninereeds a écrit :
Google Groups appears to have thrown away my original reply, so sorry
if this appears twice...



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.

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)
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.
As they are in C and C++.

The relation between the name and the named object are somewhat
different in Python.
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.
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).
 
N

Neil Cerutti

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' !-)

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.
 
B

Bruno Desthuilliers

Neil Cerutti a écrit :
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 not sure this is really an "advantage" here.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,967
Messages
2,570,148
Members
46,694
Latest member
LetaCadwal

Latest Threads

Top