Password cracking commenting in Python I am having some difficulty with commenting my code for a Python password cracking application I have created. I have commented on the majority of the code. However, I was wondering if anyone could suggest anymore comments I need as my instructor is really stick on me commenting my code.

import time 
import string

#Variables
max_attempts = 999999999 #the number of attempts the system makes for a brute-force attack
start       = time.time() #monitors the time length
chars       = list(string.printable) #all the possible ascii characters which the system uses to determine the password
base        = len(chars) #the base for conversion
n           = 0 #number of attempts
solved      = False
password    = input("Enter your password:") #the feature which allows the user to enter in their chosen password

print(chars) #record of previous password attempts

# converts number N base 10 to a list of digits base b
def numberToBase(n, b):
    digits = []
    while n: # takes n and the finds the modulus, the remainder of n % b
        digits.append(int(n % b)) # then it will append that to a list
        n //= b # following on it will then divide n into b
    return digits[::-1] #returns those digits into reverse order from -1, the end to the beginning


# checks if the user has inputted empty text/numbers/symbols
if password == '':

    print('Your password is empty')
    solved = True

elif password == chars[n]:
    print('Your password is ' + chars[n])
    solved = True

else:
    n = 1

#Begins systematically checking the password
if not solved:
    while n &lt; max_attempts:
        list = numberToBase(n, base)
        print(list)
        word = ''
        for c in list: #loop through each of the characters in the list
            word += str(chars[c]) #adds the characters from the list to a word
        print(word)
        if password == word: #checks if the password equals to the word the system has generated
            solved = True # if the generation is correct the password will then commence to print statements
            print('***Results***')
            print('Password: ' + word)
            print('Attempts: ' + str(n))
            print('Time: ' + str((time.time() - start)) + ' sec') 
            break #stops the loop
        else:
            n += 1 #however if the password generation isn't correct, we increment with n

# the password is beyond max_attempts
if not solved:
    print('Unsolved after ' + str(n) + ' attempts!')
1. The purpose of comments

Comments are a tool that you use in order to make code easier to understand and easier to maintain. But they are not the best tool to achieve that aim. Comments increase the amount of text that has to be read (you have to read the comment as well as the code) and there is a risk that when code is changed, a programmer will forget to change the nearby comments, leading to nonsense like the comments in this question.

So comments are a last resort when you can't make the code clear enough by other means. Before writing a comment you should ask these questions:


Do functions have documentation explaining their arguments and results? (In Python, do they have docstrings?)
Are there test cases (or documentation examples) demonstrating the correct behaviour of the code?
Do function names clearly describe what they do? And do variable names clearly indicate the meaning of their values?
Is the code written in the simplest, clearest way?


Only when the answers are all "yes", and the code is still not clear, should you consider writing a comment.

2. Worked example

Let's take the numberToBase function and ask these questions:

# converts number N base 10 to a list of digits base b
def numberToBase(n, b):
    digits = []
    while n: # takes n and the finds the modulus, the remainder of n % b
        digits.append(int(n % b)) # then it will append that to a list
        n //= b # following on it will then divide n into b
    return digits[::-1] #returns those digits into reverse order from -1, the end to the beginning



There's no documentation. Let's turn the first comment into a docstring:

def numberToBase(n, b):
    """Convert the number n to base b and return a list of digits."""
    digits = []
    while n:
        digits.append(int(n % b))
        n //= b
    return digits[::-1]

There are no examples. Let's add some:

def numberToBase(n, b):
    """Convert the number n to base b and return a list of digits.

        &gt;&gt;&gt; numberToBase(1234, 10)
        [1, 2, 3, 4]
        &gt;&gt;&gt; numberToBase(1023, 2)
        [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]

    """
    digits = []
    while n:
        digits.append(int(n % b))
        n //= b
    return digits[::-1]


These are in the form of doctests so that they can be automatically checked using the doctest module.
There are bunch of improvements we can make to the names. (i) Something like number_to_digits would be clearer than numberToBase since the result is a list of digits. (ii) base would be clearer than b. (iii) The built-in function divmod would make it clear that we are computing the division and modulus. (iv) The name digit for the modulus would make its meaning clear. (v) Using the built-in functions list and reversed would make it clear that we are computing a list in reverse order.

def number_to_digits(n, base):
    """Convert the number n to a list of digits in the given base.

        &gt;&gt;&gt; number_to_digits(1234, 10)
        [1, 2, 3, 4]
        &gt;&gt;&gt; number_to_digits(1023, 2)
        [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]

    """
    digits = []
    while n:
        n, digit = divmod(n, base)
        digits.append(digit)
    return list(reversed(digits))

The code seems clear and simple now: there is no need to add any comments.


3. Other review points


When n is 0, the result is an empty list. It might be better to return the list [0].
When b is 1, the function goes into an infinite loop. It might be better to raise an exception in this case.