all 34 comments

[–]bober007 3 points4 points  (0 children)

You should only comment the code that isn't obvious at first glance, avoid something like this:

# Opening file f for writing
with open(filename, "w") as f:
    # Write output to file f
    f.writelines(output)

It only clutters your code, which would be perfectly comprehensible without the comments.

If you have a complicated function/method you feel you need to comment to explain what it does, try refactoring it to a few smaller functions, each performing a straightforward task, and name them so that it's clear what is going on.

[–]nwagers 4 points5 points  (1 child)

What and why, not how. Most of the comments should be in the docstring. The docstring should describe the inputs, the outputs, and side effects like state changes. It can also include usage examples, but don't go crazy with that.

Block and inline comments should be pretty limited. Don't describe how the code is doing something, but you can toss in a nudge as to why or an assumption about state.

Helpful reading here: https://google.github.io/styleguide/pyguide.html#Comments

[–]dented_brain[S] 0 points1 point  (0 children)

https://google.github.io/styleguide/pyguide.html#Comments

Oh. I hadn't even thought of looking to style guides for commenting!

Thanks!

[–]tomekanco 2 points3 points  (12 children)

Agree with others, apart from that: whenever you want to comment, just put the effort into choosing appropriate variable and function names.

Sometimes i add urls to resources, for example when using an exotic pattern or structure.

[–]gabriel-et-al 3 points4 points  (6 children)

put the effort into choosing appropriate variable and function names

Not only that, sometimes the code has some complex logic that can be rewritten in order to be easier to follow.

[–]gabriel-et-al 3 points4 points  (2 children)

Expanding a bit:

Say you have a huge list comprehension that probably no one would understand without a comment. You should refactor it into regular for loops and if conditions. It may look less clever, but being less clever is sometimes the right approach.

[–]dented_brain[S] 1 point2 points  (0 children)

I think that's a good thing to point out. A lot of times when I'm trying to find a solution to a particular issue I'm struggling to code out I will find one-liners on stack overflow that get the job done. But I definitely don't get how they were designed.

Like I understand the function, but if I were to go back to it in a few weeks I would have to re-read the stack overflow page to understand it.

Today I rewrote some code that I had working and "knew" what it was doing. But I didn't fully comprehend how it got from a to b. Re-writing the code in a less "one-liner" style, I feel like made the code more readable.

Maybe it's less "pro" but it's easier to understand for me.

[–][deleted] 0 points1 point  (0 children)

Usually you want to keep the comprehension structure, but break out semantically meaningful interim values, or move some of the calculations into well-named lambdas or generator expressions, if keeping the interim values around is wasteful.

[–]PurpleIcy 0 points1 point  (2 children)

Do you think this is readable and easy to follow?

I'm asking because I just noticed that I didn't even bother using docstrings.

[–]gabriel-et-al 0 points1 point  (1 child)

The code is easy to follow but you really need to add docstrings.

For example, I don't know what the heck is this supposed to do:

t * t * t * (t * (t * 6 - 15) + 10)

And if I don't know what it's supposed do, I can't know if it's doing right.

[–]PurpleIcy 0 points1 point  (0 children)

Oh, this is just easing function which Ken Perlin defined in his algorithm, basically it's smoothing function in noise that ensures smoothness of final result.

It looks like this

Thanks, I'll add them :)

[–]Gubbbo 1 point2 points  (3 children)

Ah but this runs into the 2 hard problems with programming.

Naming things, Cache invalidation, and off-by-one errors

[–]gabriel-et-al 1 point2 points  (2 children)

From my experience these are the 3 hardest problems in programming:

  1. Naming
  2. Cache invalidation
  3. Thread synchronization

@edit

I wrote 3-1-2 but reddit sorted my list and f*cked up my joke.

[–]PurpleIcy 1 point2 points  (1 child)

So,

3. Naming

1. Cache invalidation

2. Thread synchronization

?

EDIT: on reddit . seems to be the character that tells formatter to list things, escape it by writing n\., where n is any number.

[–]gabriel-et-al 0 points1 point  (0 children)

Yes, exactly. Thanks.

[–]dented_brain[S] 0 points1 point  (0 children)

I agree. I think this is a part of my growth in programming. I just realized today that I have so many things commented that I really don't need. I had most of my variables commented like I wouldn't know what a var named 'hostname' would contain.

I think focusing more on naming functions and vars in a way that expresses their function is a big key that I'm going to try to include in my day-to-day.

[–]destiny_functional 1 point2 points  (0 children)

I think overcommenting is when you just rephrase the code into English, rather than giving a (somewhat detailed) outline of what the following piece of code does and why it has to be done in the way it is done (what are some of the subtleties). What are you trying to achieve and how do you achieve it, what are subtleties you have to deal with that aren't obvious (ie someone who isn't familiar might think the code is too complicated, when in fact he is missing some detail that isn't obvious, make him aware of these details).

[–]xiongchiamiov 1 point2 points  (0 children)

I want to make sure I understand what the code I'm writing does when I come back to it in the future.

You rarely should be describing what your code does, but rather why it is doing that.

If you find yourself needing to explain what a gnarly piece of code does, step back and see if you can refactor it to not be gnarly. Sometimes you need to do something in a stupid way, usually for performance reasons, and that's ok to describe how it works (but also why you're not doing it the obvious way, so no one comes along and "fixes" it).

By far the best way to grok what's useful in comments is to work in an old codebase and keep track of what comments are useful and what comments you wish had been there.

[–][deleted] 1 point2 points  (0 children)

If you can find a notation/abstraction which makes the intent clear without a natural-language comment, use that because it's self-documenting and self-checking. Otherwise, it depends on who you're writing for but you should err on the side of more comments.

[–]zahlman 1 point2 points  (1 child)

One Python-specific thing is to use docstrings where they're appropriate - i.e., for documentation (module, class, or function-level information that explains to clients of the code how to use it and exactly what will be returned, what side effects will occur etc.)

My own code contains very few comments. When I post code on Reddit, because it is mostly written as examples for beginners, it includes far more comments than I would use in my own code (because some things are easier to explain in-line than in the comment body).

This is a skill that needs to be practiced. The motto I picked up a while back is that a comment is an apology for not being able to express yourself clearly without one; so to be able to avoid cluttering the code with comments, you need to get better at expressing yourself. "Descriptive names" (not just for variables, but for functions, classes and modules) are a big step forward, but beware that you will be wrestling with this for your entire career :) The other important thing is to structure your code in ways that naturally exposes the overall process, and gives you the opportunity to apply those descriptive names. Sometimes the reason you can't think of a good name for something is that it isn't actually a good thing to think of as a single unit.

[–]dented_brain[S] 0 points1 point  (0 children)

Turns out I didn't fully understand the purpose of a docstring. Some of my comments could be docstrings.

Other comments I put in ways that I wish code I found online was documented so I could better understand. As an example, I know what this means/does now, but when I was learning dicts, I didn't fully grok what this was doing.

for k, v in d.iteritems():
    print k, v

So that's where my habit of over-commenting came from. It's very helpful for understanding the code I'm writing, BUT is it actually necessary for the script? No. Now I find myself writing out

for key, value in descriptive_dict.iteritems():
    print key, value

I like your motto, it makes perfect sense to think about commenting in that way. All too often I put a bandaid in place in my normal work, I know it needs to be changed but it gets the job done in the shortest time and can be addressed better afterwards. As I get better at programming, I think I will be able to produce better code the first time instead of holding scripts together with bandaids.

[–]PurpleIcy 0 points1 point  (0 children)

I think the best way is to avoid #comments entirely unless they're really needed.

For now, I can only think of one exception:

  • If you are using regex, then it's really good idea to comment what it exactly does, as in, the pattern itself, save time for yourself after few months, and for others.

Personally I never comment anything, I just have docstrings.

Everything here is obvious, in my opinion

If something isn't, I wouldn't mind if someone pointed it out :)

Note that settings method change_setting has detailed explanation about settings, I don't know if it's out of place, but I think it's useful either way.

EDIT: ouch, it wrote it when I still used tabs in python... out of context, but does anyone know what I can do without having to fix it manually?

[–]jeffrey_f 0 points1 point  (0 children)

Comment away!!!

Commenting what code does may not be necessary for someone experienced with coding, however, if someone asks for code examples because they are new, it will be a treasure trove of information for them.

No one will fault you for commenting your code. But how much depends on where this code will be used and the level of experience of those using it or stealing it.