kj wrote:
Below is my very firs python script.

This was just a learning exercise; the script doesn't do anything
terribly exciting: for an argument of the form YYMMDD (year, month,
day) it prints out the corresponding string YYMMDDW, where W is a
one-letter abbreviation for the day of the week.  E.g.

% wd 090511
090511M

The script runs OK, but I can still see a few areas of improvement,
for which I could use your advice.

1. The name of the BadArgument exception class defined in the script
   does not seem to me sufficiently specific.  If one were to import
   the script in order to reuse its wkday_abbrev function, I'd like
   this exception's name to be more unequivocally tied to this
   script.  What I'm looking for is something like a "namespace"
   for this script.  What's the pythonic way to construct a namespace?

2. In some python modules I've seen the idiom

   if __name__ == "__main__":
      # run some tests here

   I'd like to set up tests for this script, mostly to ensure that
   it handles the error cases properly, but I'm alread using the
   idiom above to actually run the script under normal operation.
   What's the typical python idiom for running tests on a *script*
   (as opposed to a module that is normally not supposed to be run
   directly)?

3. Still on the subject of testing, how does one capture in a
   variable the output that would normally have gone to stdout or
   stderr?

4. What's the python way to emit warnings?  (The script below should
   warn the user that arguments after the first one are ignored.)

5. The variable wd is meant to be "global" to the script.  In other
   languages I've programmed in I've seen some typographic convention
   used for the name of such variables (e.g. all caps) to signal
   this widened scope.  Does python have such a convention?

Any comments/suggestions on these questions, or anything else about
the script, would be much appreciated.

TIA!

kynn


----------------------------------------------------------------
from optparse import OptionParser
import re
import datetime
import sys

class BadArgument(Exception): pass

wd = ("M", "T", "W", "H", "F", "S", "U")

def wkday_abbrev(str):
  try:
    mm = re.match("(\d{2})(\d{2})(\d{2})\Z", str)

    y, m, d = map(lambda x: int(mm.group(x)), (1,2,3))

    if y < 38: y = y + 1900
    else: y = y + 2000

    return wd[datetime.datetime(y, m, d).weekday()]
  except (AttributeError, ValueError):
    raise BadArgument()


def main():

  usage = '''Usage: %prog [options] YYMMDD
       %prog -h|--help
'''

  parser = OptionParser(usage=usage)
  parser.add_option("-n", "--no-newline", dest="nonl",
                    action="store_true", help="omit newline in output")

  (options, args) = parser.parse_args();

  try:
    sys.stdout.write("%s%s" % (args[0], wkday_abbrev(args[0])))
    if not options.nonl: print

  except (IndexError, BadArgument):
    print usage
    sys.exit(1)
  except: raise

if __name__ == "__main__": main()


Other replies cover most of your questions nicely. But for the testing question:

Rename this script to some other name, and call it a module
Write a new script with just three lines in it:

import  othermodule

if __name__ == "__main__":
  othermodule.main()



Now your testing code can go in "othermodule.py"

Note that I would put the argument parsing logic in the new file, so parts of main() would actually move. Normally I'd call main() with two arguments - options, args

Your use of optparse could be more streamlined. For example, it'll build the help string for you, based on the various calls to add_option(), and it includes its own -h and --help implicitly.


--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to