Joe Useless
Writes A Program
An Everyday
Person's Guide to Software Development
Rob Andrews
Writing computer programs to
distribute is a process, but it can be a simple one. This article follows
our hero Joe Useless on his journey from wanting a simple problem solved to
giving his friends the answer in a program they can use over and over. This article is a work in progress, and helpful suggestions are welcome.
Step
1: Have a problem to solve.
(You can also think of this step as "Think of something you want to do.")
Joe Useless has taken a job working as a clerk at ACME, and enjoys his
job for the most part. But clerks in his department have to do a lot of something
that Joe hates. They have to compare obscure lines of text, and his supervisor
insists that there is no room for error.
Fortunately for Joe, ACME takes the enlightened approach of allowing him
to run Python on his PC. "Whatever gets the job done right," insists his
supervisor.
Step 2: Find
a way to do it at all.
Joe has used Python before and feels certain he remembers a simple way
to do comparisons, so after spending a few minutes with the Library Reference,
he turns on IDLE and tries out the cmp() built-in function:
>>> cmp('Harrelson,
Adrienne', 'Harrelson, Adrianne')
1
>>>
It looks like this might do the trick for some of their more common and
tedious comparisons. Joe gets into the habit of keeping IDLE running in
the background to double-check some of his work for a while just to make
sure.
Step 3: Tweak
it until you have code that consistently does it the way you like.
This little trick works well enough that Joe finds he has largely automated
the most annoying part of his job, to the envy of his co-workers. But Joe
isn't a Computer Scientist, and he finds that the "1/0/-1" values returned
by cmp() leave him feeling nervous that he might make accidentally mistake
"1" for "-1" and mess up the job. He doesn't want to have to look up the
meaning of the values cmp() returns, so he decides to write a function to
dress-up the output.
>>> def compare(firstArg,
secondArg):
if cmp(firstArg, secondArg) == -1:
print str(firstArg) + " is
less than " + str(secondArg)
elif cmp(firstArg, secondArg) == 0:
print str(firstArg) + " is
equal to " + str(secondArg)
else:
print str(firstArg) + " is
greater than " + str(secondArg)
This is much better. Joe's function takes the output from cmp() and displays
the result in plain English (by clerk standards, anyway), like so:
>>> compare('Harrelson,
Adrienne', 'Harrelson, Adrianne')
Harrelson, Adrienne is greater than Harrelson, Adrianne
>>>
Joe decided to use terms like
"greater than" and "less than" in the program's output, because this seemed
like a familiar way of thinking about it, especially since the same function
can be used to compare the values of numbers.
Step 4: Package
it to be used repeatedly.
Joe's co-workers are beginning to take notice now, especially since the
management is becoming less tolerant of mistakes. Joe decides to make the
function into a module that other workers can run on their own workstations.
(By this point, Joe is also becoming something of a Python zealot and wants
to see more people using it.) He adds a few lines of code to the text file
where he keeps his comparison function, turning it into a program the clerks
can start from the command line.
def compare(firstArg, secondArg):
if cmp(firstArg, secondArg) == -1:
print str(firstArg) + " is
less than " + str(secondArg)
elif cmp(firstArg, secondArg) == 0:
print str(firstArg) + " is
equal to " + str(secondArg)
else:
print str(firstArg) + " is
greater than " + str(secondArg)
if __name__ == '__main__':
import sys
compare(sys.argv[1], sys.argv[2])
Joe was surprised to discover
how little effort he had to put into making his handy little function into
a full-fledged program. In Programming Python by Mark Lutz, he found
out that if a Python script is run as a program, a built-in variable called
"__name__" is assigned a special string called "__main__", and that you can check for
this with a simple "if" statement like the one he added. (He even thinks he half-way understands what this means!)
Now if his file is started from the command line as a program instead of
imported into an interactive interpreter such as IDLE, the clerk who starts
the program can enter the two strings needing to be compared after the program
name. (This is sometimes referred to as "calling a program with arguments".
The first of the two strings entered is the first argument, which the program
sees as sys.argv[1], and the second string is the second argument, or sys.argv[2].)
The two command-line argument strings are passed to the compare function
in the last line of the program. So compare() starts up with sys.argv[1]
as firstArg and sys.argv[2] as secondArg. It then calls cmp() and passes
firstArg and secondArg to it, then prints a statement to the screen about
how the two strings compared.
Step 5: Make
it bullet-proof.
Joe's fellow clerks keep making minor mistakes when running the program,
and the department uses a lot of temporary workers. Joe doesn't want to
spend too much time showing people how to use the program, so he decides
to have the program itself remind the user of the right way to use it when
the most common mistakes are made.
def compare(firstArg, secondArg):
if cmp(firstArg, secondArg) == -1:
print str(firstArg) + " is
less than " + str(secondArg)
elif cmp(firstArg, secondArg) == 0:
print str(firstArg) + " is
equal to " + str(secondArg)
else:
print str(firstArg) + " is
greater than " + str(secondArg)
if __name__ == '__main__':
import sys
if len(sys.argv) != 3:
print '''********************\n
Usage suggestion:\n
python comparison.py argument1 argument2\n
\n
For example:\n
C:\Python22\python comparison.py "Jolie, Angelina" "Useless, Joe"\n
********************'''
else:
compare(sys.argv[1], sys.argv[2])
Now, if a user gives the program too many or too few arguments, the program
suggests an example of correct usage instead of producing an error message.
For example, if the user enters only one name to compare:
C:\Python22>python comparison.py
"Stallman, Richard"
********************
Usage suggestion:
python comparison.py argument1 argument2
For example:
C:\Python22\python comparison.py "Jolie, Angelina" "Useless, Joe"
********************
Joe hopes that this will be enough
of a reminder for people that he will only be have to spend a few minutes
with them at first to train them in how to use the program meaningfully.
Step 6: If you
haven't already done it, comment your code.
Useless Joe's supervisor is happy, as is the supervisor's manager. The
clerks are happy. And Joe wants this trend to continue, so he takes a little
time to sit down and add comments to the source code of the program he has
written. Even though this is a simple program, it would not make a lot of
sense to someone who has never seen source code. If someone needs to change
the code later (maybe even himself), he wants the code to look good and
make sense without anyone having to waste much time figuring it out. Joe
decides to add some comments describing what the different parts of the program
are instead of describing every little technical detail. He also comments
the date the program was last edited, so if the program is updated at some
point, it will be easy to tell which version is in use on any given clerk's
PC.
#!/usr/bin/python
#
# comparison.py by Joe Useless for ACME clerks
# Last edited on May 22, 2002
# This is the function that does all the work.
# Arguments sent to the program are compared with the
# Python built-in function cmp()
def compare(firstArg, secondArg):
# This if/elif/else block reformats cmp() output
# so clerks can make out the meaning with fewer mistakes
if cmp(firstArg, secondArg) == -1:
print str(firstArg) + " is less
than " + str(secondArg)
elif cmp(firstArg, secondArg) == 0:
print str(firstArg) + " is equal
to " + str(secondArg)
else:
print str(firstArg) + " is greater
than " + str(secondArg)
# This is the main method, which makes it possible to run the
# comparison as a top-level program instead of just by calling
# the compare function from within another program, such as
# a python interactive interpreter.
if __name__ == '__main__':
import sys
# If a clerk calls the program with the wrong number
of
# arguments, print an example of correct usage.
if len(sys.argv) != 3:
print '''********************\n
Usage suggestion:\n
python comparison.py argument1 argument2\n
\n
For example:\n
C:\Python22\python comparison.py "Jolie, Angelina" "Useless, Joe"\n
********************'''
# If the clerk calls the program correctly, perform the
# compare function with the arguments provided by the
clerk.
else:
compare(sys.argv[1], sys.argv[2])
Now Joe Useless feels satisfied with the program. He feels the comments are
okay for a program this small, and by putting his program in the hands of
other clerks, he is beginning to get an idea of how the program can be improved
some more.
Now all that remains is to send his
program to Useless Python
!