5
\$\begingroup\$

I have written a simple python program which takes a number from the user and checks whether that number is divisible by 2:

# Asks the user for a number that is divisible by 2                                  
# Keep asking until the user provides a number that is divisible by 2.               
print 'Question 4. \n'

num = float(raw_input('Enter a number that is divisible by 2: '))

while (num%2) != 0:
    num = float(raw_input('Please try again: '))
print 'Congratulations!'

I would appreciate any feedback on this code, areas for improvement and/or things that I could have done differently.

\$\endgroup\$
3
\$\begingroup\$

Well, first of all, you should put code in an if __name__ == '__main__': block to make sure it doesn't run whenever the file is imported. Thus, just copy pasting:

if __name__ == '__main__':
    print 'Question 4. \n'

    num = float(raw_input('Enter a number that is divisible by 2: '))
    while (num%2) != 0:
        num = float(raw_input('Please try again: '))

    print 'Congratulations!'

The next thing to notice is that a number being even is actually a fairly common check to make. Such things should be turned into functions. Mostly copy-pasting again:

def is_even(num):
    """Return whether the number num is even."""
    return num % 2 == 0

if __name__ == '__main__':
    print 'Question 4. \n'

    num = float(raw_input('Enter a number that is divisible by 2: '))
    while not is_even(num):
        num = float(raw_input('Please try again: '))

    print 'Congratulations!'

Notice the docstring: it's important to document your code, and while the purpose of is_even is obvious, getting into the habit of adding documentation is good. You could also put the following docstring at the top of the file:

"""Provide the is_even function.

When imported, print prompts for numbers to standard output and read numbers
from standard input separated by newlines until an even number is entered.  Not
entering an even number raises EOFError.

"""

In my opinion, you should get into the habit of programs working on files, not on user input; you'll find that programs are much easier to chain that way.

Possible further improvements are handling the EOFError (catching it and printing something like "No even numbers entered."), splitting the repeating functionality into a main function (questionable use), and maybe adding a read_float function that would be something along the lines of

def read_float(prompt):
    """Read a line from the standard input and return it as a float.

    Display the given prompt prior to reading the line.  No error checking is done.

    """
    return float(raw_input(prompt))

Here too, there is plenty of room for error checking.

I removed the parentheses around (num%2) as I went along; PEP8 discourages these, if I remember correctly. Either way, it is a very valuable read.

\$\endgroup\$
2
  • \$\begingroup\$ Thanks for the great feedback, I found it very helpful. You suggested that I put if __name__ == '__main__': into my code. Any I correct in thinking that the code will then only be run when the file is called directly? If so, how would you call the code indirectly through another file? \$\endgroup\$ Jan 29 '12 at 10:50
  • \$\begingroup\$ @TomKadwill - That is correct; if you feel the need to call it from another file, put it into a function (which is often called main), as far as I've seen. \$\endgroup\$ Jan 29 '12 at 11:16
2
\$\begingroup\$
print 'Question 4. \n'

num = float(raw_input('Enter a number that is divisible by 2: '))

Some error-handling would be good here, because float will raise a ValueError if the input can't be converted.

while (num%2) != 0:

This is correct, but over-fussy. The parentheses are unnecessary, because python's precedence rules mean that modulo will be evaluated before any comparison operators.

    num = float(raw_input('Please try again: '))

The script should allow the user to exit gracefully if they don't want to continue.

Here's one possible way to re-write your script based on the suggestions above:

print 'Question 4. \n'

prompt = 'Enter a number that is divisible by 2: '

while True:
    data = raw_input(prompt)
    if data:
        try:
            number = float(data)
        except ValueError:
            print 'Invalid input...'
        else:
            if number % 2 == 0:
                print 'Congratulations!'
                break
        prompt = 'Please try again: '
    else:
        # allow the user to exit by entering nothing
        print 'Goodbye!'
        break
\$\endgroup\$
1
  • \$\begingroup\$ Thanks for the feedback, particularly on error-handling. I can see how your script contains more error checking and is more elegant. I'll take this into account when writing my next script. \$\endgroup\$ Jan 29 '12 at 10:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.