Q's on my first python script

kj socyl at 987jk.com.invalid
Sun May 10 08:52:21 EDT 2009

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

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

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

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.



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):
    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();

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

  except (IndexError, BadArgument):
    print usage
  except: raise

if __name__ == "__main__": main()

NOTE: In my address everything before the first period is backwards;
and the last period, and everything after it, should be discarded.

More information about the Python-list mailing list