how to abbreviate dimension following the PEP8 rules? - python

I must add a function for creating 3D textures.
I am using snail case in the entire module.
My choices are:
def texture_3d(...):
pass
def texture_3D(...):
pass
def texture3D(...):
pass
What should be the name of the function?
I am not interested in opinions: which one looks better. I need a few references to other modules to see the best practice.
Please mention at least 1 module having similar functions.

PEP 8 states lowercase with underscore separation between words for function names. Now, because it seems opinionated if 3d/3D is an actual word, you'll get conflicts between the names texture_3d and texture3d (with d being lowercase).
Looking at a number of numpy functions, for example, lagval3d, laggrid3d, hermegrid3d the name texture3d looks like a good choice.
Searching for similar names in the matplotlib docs yields a mixed result between <name>3d and <name>_3d.
In short, both these names seem to be accepted, based on two major packages. Boils down to personal choice between the two.

Rather than depending on mere human opinion, perhaps we could ask the horse? (As in 'getting it from the horse's mouth'.) In other words, use pylint.
I modified your code so that it would generate fewer messages.
''' some information here'''
def texture_3d(parameters):
''' a docstring'''
return parameters
def texture_3D(parameters):
''' a docstring'''
return parameters
def texture3D(parameters):
''' a docstring'''
return parameters
The results of pylint were:
************* Module temp
C: 7, 0: Invalid function name "texture_3D" (invalid-name)
C: 11, 0: Invalid function name "texture3D" (invalid-name)
------------------------------------------------------------------
Your code has been rated at 6.67/10 (previous run: 5.00/10, +1.67)
Which just leaves the option texture_3d.

From PEP-8:
Method Names and Instance Variables
Use the function naming rules:
lowercase with words separated by underscores as necessary to improve
readability.
This suggests to me that your first option is the most compliant of the three.

Short answer: texture_3d.
PEP-8 says about function names:
Function names should be lowercase, with words separated by
underscores as necessary to improve readability.
mixedCase is allowed only in contexts where that's already the
prevailing style (e.g. threading.py), to retain backwards
compatibility.
Since "texture" and "3d" are two separate words, it is good practice to put an underscore between them. Furthermore the function name should be lowercase, so 3D is not allowed.

Related

naming conventions to differentiate a function (action) from a variable (option) in python

Often I'll have little functions that do something. e.g. save_csv(), show_plot(), and then larger functions which do a bunch of stuff and optionally call the little functions. What's a decent naming convention for this to differentiate e.g. save_csv() as a function, and save_csv as a flag?
In C etc it's not unusual to use Hungarian notation and prefix the variables with a 'b' for 'boolean'. But I don't think that's very pythonic. And I've tried 'do_' prefix for the flag and it kind of works but is ugly and confusing too. I'm wondering if there's any conventions for this?
I couldn't see anything in pep8.
https://www.python.org/dev/peps/pep-0008/#descriptive-naming-styles
e.g.
def foo(..., b_resample, b_save_csv, b_save_plot, b_show_plot, b_compare):
# do some stuff
if b_resample:
# do more stuff
resample(...)
if b_show_plot:
# do more stuff
show_plot(...)
if b_compare:
# do more stuff
compare(...)
# do more stuff
if b_save_csv:
# do more stuff
save_csv(...)
UPDATE:
Bearing in mind that the arguments to the function are public facing, I'd like them to be 'decent' which is why I'm not a fan of hungarian notation or leading underscores in this case. However I am considering switching to the below, where the public facing args are human readable, whereas internally they have leading underscores. Is this common practice?
def foo(..., **kwargs):
_resample = kwargs.get('resample', False)
_show_plot = kwargs.get('show_plot', False)
_save_plot = kwargs.get('save_plot', True)
_compare = kwargs.get('compare', True)
_save_csv = kwargs.get('save_csv', True)
# do some stuff
if _resample:
# do more stuff
resample(...)
if _show_plot:
# do more stuff
show_plot(...)
if _compare:
# do more stuff
compare(...)
# do more stuff
if _save_csv:
# do more stuff
save_csv(...)
Taken straight from PEP8:
Function names should be lowercase, with words separated by underscores as necessary to improve readability.
Variable names follow the same convention as function names.
So I don't think there's a "pythonic" convention to differentiate a function from a variable that share the same name. I think it's more of a personal choice and as such, I'd personally use a variable called has_save_csv or is_save_csv(as Ramazan Polat has already mentioned).
Update Yes, it is a good practice to have variables starting with a leading underscore when you plan on using them internally. You can read more on this excellent article that succinctly summarizes the meaning of underscores.
Ideally, a boolean identifier should end with an adjective, so I would use a suffix like "wanted"; for instance plot_wanted.
You can use SaveCSV for method name and save_csv for attribute name, although I don't recommend it. Because usually methods 'do' something for an object, while attributes are merely a state of an object.
In your case, I recommend you to use save_csv() for method name and is_save_csv as attribute name.
Functions should be action verbs (like run, check, or save) describing what they DO. Whereas, variables should be words that describe what they ARE (so, usually nouns/adjectives, though some "passive" verbs are in this category like "has" or "needs")
In your example, save_csv() for the function and something like has_save_csv or save_needed as other users have suggested for the variable.

How to work with access modifiers in python & __doc__?

A newbie to oops concepts, so basically i know mostly general oops concepts. but trying a lot to make a variable inside a class public private and protected. I know that they are done using 1 & 2 underscores with a variable name. How do u initialise acess modifiers, call them set a value to them ? Basically i'm looking for a general example/syntax.
also i have been reading a lot about python. but i have never found something related to doc can somebody please give me a overview as to how this works as well.
Thanks a ton
Python has no concept of a private field or method. However, identifiers that begin with two underscores, but do not end with two underscores, will be "mangled" with the class name to prevent accidental overrides. You can find more information here.
That's a part of the language. It's conventional as a programming practice that identifiers beginning with single underscores should be considered private. That's a polite request that is not enforced...but it's a Real Good Idea to leave single-underscore names along.
The other underscore convention that I'm aware of is that a name consisting of a single underscore is often used in a for loop, list comprehension or generator expression when the control variable is not going to be used in the loop. For example, Doing something n times might look like:
for _ in range(n):
...statements to repeat
Python does not have private variables, starting an attribute with an underscore (_) is a way of indicating it is private to other programmers, see here for more details.
Since there are no private variables ones starting with an underscore can be modified like any other.
class MyClass():
"""Docstrings are important"""
def __init__(self):
self._myPrivateNumber = 42
C = MyClass()
C._myPrivateNumber #42
C._myPrivateNumber = 1
C._myPrivateNumber #1
setattr(C, '_myPrivateNumber', -1)
C._myPrivateNumber #-1
I am assuming you also want to know about __doc__. It is called a docstring and is used to document your objects. It is created from the string immediately after the declaration, e.g. the doc string of C, C.__doc__ is the string "Docstrings are important" You can read about how it is created here. If a docstring is not provide __doc__ will be ''. They are also used to crete the help information i.e. help(C) will use the docstring.

Why does Pylint object to single-character variable names?

I'm still getting used to Python conventions and using Pylint to make my code more Pythonic, but I'm puzzled by the fact that Pylint doesn't like single character variable names. I have a few loops like this:
for x in x_values:
my_list.append(x)
and when I run pylint, I'm getting Invalid name "x" for type variable (should match [a-z_][a-z0-9_]{2,30} -- that suggests that a valid variable name must be between 3 and 31 characters long, but I've looked through the PEP8 naming conventions and I don't see anything explicit regarding single lower case letters, and I do see a lot of examples that use them.
Is there something I'm missing in PEP8 or is this a standard that is unique to Pylint?
A little more detail on what gurney alex noted: you can tell Pylint to make exceptions for variable names which (you pinky swear) are perfectly clear even though less than three characters. Find in or add to your pylintrc file, under the [FORMAT] header:
# Good variable names which should always be accepted, separated by a comma
good-names=i,j,k,ex,Run,_,pk,x,y
Here pk (for the primary key), x, and y are variable names I've added.
Pylint checks not only PEP8 recommendations. It has also its own recommendations, one of which is that a variable name should be descriptive and not too short.
You can use this to avoid such short names:
my_list.extend(x_values)
Or tweak Pylint's configuration to tell Pylint what variable name are good.
In explicitly typed languages, one-letter name variables can be ok-ish, because you generally get the type next to the name in the declaration of the variable or in the function / method prototype:
bool check_modality(string a, Mode b, OptionList c) {
ModalityChecker v = build_checker(a, b);
return v.check_option(c);
}
In Python, you don't get this information, so if you write:
def check_modality(a, b, c):
v = build_checker(a, b)
return v.check_option(c)
you're leaving absolutely no clue for the maintenance team as to what the function could be doing, and how it is called, and what it returns. So in Python, you tend to use descriptive names:
def check_modality(name, mode, option_list):
checker = build_checker(name, mode)
return checker.check_option(option_list)
And you even add a docstring explaining what the stuff does and what types are expected.
Nowadays there is also an option to override regexp. I.e., if you want to allow single characters as variables:
pylint --variable-rgx="[a-z0-9_]{1,30}$" <filename>
So, Pylint will match PEP8 and will not bring additional violations on top. Also you can add it to .pylintrc.
The deeper reason is that you may remember what you intended a, b, c, x, y, and z to mean when you wrote your code, but when others read it, or even when you come back to your code, the code becomes much more readable when you give it a semantic name. We're not writing stuff once on a chalkboard and then erasing it. We're writing code that might stick around for a decade or more, and be read many, many times.
Use semantic names. Semantic names I've used have been like ratio, denominator, obj_generator, path, etc. It may take an extra second or two to type them out, but the time you save trying to figure out what you wrote even half an hour from then is well worth it.
pylint now has good-names-rgxs, which adds additional regex patterns to allow for variable names.
The difference is that that variable-rgx will override any previous rules, whereas good-names-rgxs adds rules on top of existing rules. That makes it more flexible, because you don't need to worry about breaking previous rules.
Just add this line to pylintrc to allow 1 or 2 length variable names:
good-names-rgxs=^[_a-z][_a-z0-9]?$
^ # starts with
[_a-z] # 1st character required
[_a-z0-9]? # 2nd character optional
$ # ends with
The configuration that pylint itself generates will allow i, j, k, ex, Run, though not x,y,z.
The general solution is to adjust your .pylintrc, either for your account ($HOME/.pylintrc) or your project (<project>/.pylintrc).
First install pylint, perhaps inside your .env:
source myenv/bin/activate
pip install pylint
Next run pylint, but the file is too long to maintain manually right from the start, and so save on the side:
pylint --generate-rcfile > ~/.pylintrc--full
Look at the generated ~/.pylintrc--full. One block will say:
[BASIC]
# Good variable names which should always be accepted, separated by a comma.
good-names=i,
j,
k,
ex,
Run,
_
Adjust this block as you like (adding x,y,..), along with any other blocks, and copy your selected excerpts into ~/.pylintrc (or <project>/.pylintrc).

Docstrings vs Comments

I'm a bit confused over the difference between docstrings and comments in python.
In my class my teacher introduced something known as a 'design recipe', a set of steps that will supposedly help us students plot and organize our coding better in Python. From what I understand, the below is an example of the steps we follow - this so call design recipe (the stuff in the quotations):
def term_work_mark(a0_mark, a1_mark, a2_mark, ex_mark, midterm_mark):
''' (float, float, float, float, float) -> float
Takes your marks on a0_mark, a1_mark, a2_mark, ex_mark and midterm_mark,
calculates their respective weight contributions and sums these
contributions to deliver your overall term mark out of a maximum of 55 (This
is because the exam mark is not taken account of in this function)
>>>term_work_mark(5, 5, 5, 5, 5)
11.8
>>>term_work_mark(0, 0, 0, 0, 0)
0.0
'''
a0_component = contribution(a0_mark, a0_max_mark, a0_weight)
a1_component = contribution(a1_mark, a1_max_mark, a1_weight)
a2_component = contribution(a2_mark, a2_max_mark, a2_weight)
ex_component = contribution(ex_mark, exercises_max_mark,exercises_weight)
mid_component = contribution(midterm_mark, midterm_max_mark, midterm_weight)
return (a0_component + a1_component + a2_component + ex_component +
mid_component)
As far as I understand this is basically a docstring, and in our version of a docstring it must include three things: a description, examples of what your function should do if you enter it in the python shell, and a 'type contract', a section that shows you what types you enter and what types the function will return.
Now this is all good and done, but our assignments require us to also have comments which explain the nature of our functions, using the token '#' symbol.
So, my question is, haven't I already explained what my function will do in the description section of the docstring? What's the point of adding comments if I'll essentially be telling the reader the exact same thing?
It appears your teacher is a fan of How to Design Programs ;)
I'd tackle this as writing for two different audiences who won't always overlap.
First there are the docstrings; these are for people who are going to be using your code without needing or wanting to know how it works. Docstrings can be turned into actual documentation. Consider the official Python documentation - What's available in each library and how to use it, no implementation details (Unless they directly relate to use)
Secondly there are in-code comments; these are to explain what is going on to people (generally you!) who want to extend the code. These will not normally be turned into documentation as they are really about the code itself rather than usage. Now there are about as many opinions on what makes for good comments (or lack thereof) as there are programmers. My personal rules of thumb for adding comments are to explain:
Parts of the code that are necessarily complex. (Optimisation comes to mind)
Workarounds for code you don't have control over, that may otherwise appear illogical
I'll admit to TODOs as well, though I try to keep that to a minimum
Where I've made a choice of a simpler algorithm where a better performing (but more complex) option can go if performance in that section later becomes critical
Since you're coding in an academic setting, and it sounds like your lecturer is going for verbose, I'd say just roll with it. Use code comments to explain how you are doing what you say you are doing in the design recipe.
I believe that it's worth to mention what PEP8 says, I mean, the pure concept.
Docstrings
Conventions for writing good documentation strings (a.k.a. "docstrings") are immortalized in PEP 257.
Write docstrings for all public modules, functions, classes, and methods. Docstrings are not necessary for non-public methods, but you should have a comment that describes what the method does. This comment should appear after the def line.
PEP 257 describes good docstring conventions. Note that most importantly, the """ that ends a multiline docstring should be on a line by itself, e.g.:
"""Return a foobang
Optional plotz says to frobnicate the bizbaz first.
"""
For one liner docstrings, please keep the closing """ on the same line.
Comments
Block comments
Generally apply to some (or all) code that follows them, and are indented to the same level as that code. Each line of a block comment starts with a # and a single space (unless it is indented text inside the comment).
Paragraphs inside a block comment are separated by a line containing a single #.
Inline Comments
Use inline comments sparingly.
An inline comment is a comment on the same line as a statement. Inline comments should be separated by at least two spaces from the statement. They should start with a # and a single space.
Inline comments are unnecessary and in fact distracting if they state the obvious.
Don't do this:
x = x + 1 # Increment x
But sometimes, this is useful:
x = x + 1 # Compensate for border
Reference
https://www.python.org/dev/peps/pep-0008/#documentation-strings
https://www.python.org/dev/peps/pep-0008/#inline-comments
https://www.python.org/dev/peps/pep-0008/#block-comments
https://www.python.org/dev/peps/pep-0257/
First of all, for formatting your posts you can use the help options above the text area you type your post.
And about comments and doc strings, the doc string is there to explain the overall use and basic information of the methods. On the other hand comments are meant to give specific information on blocks or lines, #TODO is used to remind you what you want to do in future, definition of variables and so on. By the way, in IDLE the doc string is shown as a tool tip when you hover over the method's name.
Quoting from this page http://www.pythonforbeginners.com/basics/python-docstrings/
Python documentation strings (or docstrings) provide a convenient way
of associating documentation with Python modules, functions, classes,
and methods.
An object's docsting is defined by including a string constant as the
first statement in the object's definition.
It's specified in source code that is used, like a comment, to
document a specific segment of code.
Unlike conventional source code comments the docstring should describe
what the function does, not how.
All functions should have a docstring
This allows the program to inspect these comments at run time, for
instance as an interactive help system, or as metadata.
Docstrings can be accessed by the __doc__ attribute on objects.
Docstrings can be accessed through a program (__doc__) where as inline comments cannot be accessed.
Interactive help systems like in bpython and IPython can use docstrings to display the docsting during the development. So that you dont have to visit the program everytime.

Better Python list Naming Other than "list"

Is it better not to name list variables "list"? Since it's conflicted with the python reserved keyword. Then, what's the better naming? "input_list" sounds kinda awkward.
I know it can be problem-specific, but, say I have a quick sort function, then quick_sort(unsorted_list) is still kinda lengthy, since list passed to sorting function is clearly unsorted by context.
Any idea?
I like to name it with the plural of whatever's in it. So, for example, if I have a list of names, I call it names, and then I can write:
for name in names:
which I think looks pretty nice. But generally for your own sanity you should name your variables so that you can know what they are just from the name. This convention has the added benefit of being type-agnostic, just like Python itself, because names can be any iterable object such as a tuple, a dict, or your very own custom (iterable) object. You can use for name in names on any of those, and if you had a tuple called names_list that would just be weird.
(Added from a comment below:) There are a few situations where you don't have to do this. Using a canonical variable like i to index a short loop is OK because i is usually used that way. If your variable is used on more than one page worth of code, so that you can't see its entire lifetime at once, you should give it a sensible name.
goats
Variable names should refer what they are not just what type they are.
Python stands for readability. So basically you should name variables that promote readability. See PEP20.You should only have a general rule of consistency and should break this consistency in the following situations:
When applying the rule would make the code less readable, even for
someone who is used to reading code that follows the rules.
To be consistent with surrounding code that also breaks it (maybe for
historic reasons) -- although this is also an opportunity to clean up
someone else's mess (in true XP style)
Also, use the function naming rules: lowercase with words separated by underscores as necessary to improve readability.
All this is taken from PEP 8
Just use lst, or seq (for sequence)
I use a naming convention based on descriptive name and type. (I think I learned this from a Jeff Atwood blog post but I can't find it.)
goats_list
for goat in goats_list :
goat.bleat()
cow_hash = {}
etc.
Anything more complicated (list_list_hash_list) I make a class.
What about L?
Why not just use unsorted? I prefer to have names, which communicate ideas, not data types. There are special cases, where the type of a variable is important. But in most cases, it's obvious from the context - like in your case. Quick sort is obviously working on a list.

Categories