doctest fails to NORMALIZE_WHITESPACE ?

2005-12-17 Thread David MacKay
Hello, I'm a python-list newbie. I've got a question about doctest; perhaps 
a bug report.

I really like doctest, but sometimes doctest gives a failure when the output 
looks absolutely fine to me -- indeed, even after I have gone to considerable 
effort to make my documentation match the output perfectly.

http://www.aims.ac.za/~mackay/python/compression/huffman/Huffman3.py

The above file is an example.

It's self-contained, so you can plop it into emacs and hit C-cC-c to run the 
doctests. One of them fails. 
The piece of source code concerned is here: 

>>> c = []; \
c.append(node(0.5,1,'a')); \
c.append(node(0.25,2,'b')); \
c.append(node(0.125,3,'c')); \
c.append(node(0.125,4,'d')); \
iterate(c) ; reportcode(c)   # doctest: 
+NORMALIZE_WHITESPACE, +ELLIPSIS
#Symbol Count   Codeword
a (0.5) 1
b (0.25)01
c (0.12)000
d (0.12)001
"""

And the output is: 

Failed example:
c = []; c.append(node(0.5,1,'a')); 
c.append(node(0.25,2,'b')); c.append(node(0.125,3,'c')); 
c.append(node(0.125,4,'d')); iterate(c) ; reportcode(c)   # 
doctest: +NORMALIZE_WHITESPACE, +ELLIPSIS
Expected:
#Symbol Count   Codeword
a (0.5) 1
b (0.25)01
c (0.12)000
d (0.12)001
Got:
<__main__.internalnode instance at 0xb7aee76c>
#Symbol Count   Codeword
a   (0.5)   1
b   (0.25)  01
c   (0.12)  000
d   (0.12)  001

===

I have tried numerous tweaks, and am at a loss. I am wondering whether there
is some big in doctest involving the "#" character in the output.
Or maybe I made some silly mistake.

Any advice appreciated!

Many thanks again to the authors of doctest, it gives a great feeling 
to write code in the way that doctest encourages. :-)

David

--
David J.C. MacKay [EMAIL PROTECTED] 787 9336
  http://www.aims.ac.za/~mackay/
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: doctest fails to NORMALIZE_WHITESPACE ?

2005-12-17 Thread David MacKay
Thanks everyone! Silly me  :-)

* Tim Peters <[EMAIL PROTECTED]> [2005-12-17 12:01]:
> [David MacKay]
> > Hello, I'm a python-list newbie. I've got a question about doctest; perhaps
> > a bug report.
> 
> As things will turn out, it's just a question.  That's common for newbies :-)

I've got a follow-up question motivated by my ugly backslash continuations.

> When Python doesn't "look clean", it's not Python -- and backslash
> continuation & semicolons often look like dirt to the experienced
> Python's eye.

The reason I was making those ugly single-line monsters was 
I had somehow got the impression that each fresh line starting ">>>" was tested 
_completely_separately_ by doctest; so, to preserve state I thought I had to 
write 

>>> a=[2, 5, 1];  a.sort();  print a
[1, 2, 5]

rather than 

>>> a=[2, 5, 1]
>>> a.sort()
>>> print a
[1, 2, 5]

But I see now I was wrong.  Question: 
Does doctest always preserve 
   state throughout the entire sequence of tests enclosed by `"""`, as if the 
tests were 
   entered in a single interactive session? 
Or is there a way to instruct doctest to forget its state, and start 
   the next `>>>` with a clean slate? 

Thanks very much!
David

-- 
--
David J.C. MacKay [EMAIL PROTECTED] 787 9336
  http://www.aims.ac.za/~mackay/
-- 
http://mail.python.org/mailman/listinfo/python-list


pythonic equivalent of upvar?

2005-12-20 Thread David MacKay
Dear Greater Py,


 I am writing a command-line reader for python.

 I'm trying to write something with the same brevity 
as perl's one-liner

eval "\$$1=\$2" while @ARGV && $ARGV[0]=~ /^(\w+)=(.*)/ && shift;

and with similar functionality.  I've decided I don't like 
getopt, because it seems to require me to write pages and pages 
of elif's as I add new arguments.  It slows me down, whereas the 
perlism above liberates.

My solution is a twenty-line python chunk equivalent to the perl one-liner. 
(Twenty lines because, to process a (name, value) pair, I have to find the 
current type of the variable "name" before setting "name" to righttype("value").

I'm happy with this 20-line chunk and wish to re-use it in many python programs.



 What is the pythonic way to embed a 20-line chunk of code into a function?
I'd love to define these 20 lines as a module, and reuse the module over and 
over.
but this chunk of code needs to have access to 
the local variables of main, whatever they are called. 

 In tcl, IIRC, the command "upvar" allows one function to get access to its 
parent function's local variables.

 Is there a pythonic way to tell a function "you are allowed to see all your 
parent's variables?"  Or, to tell a chunk of code, "you are just a chunk of 
code, not really a function"?


Thanks very much

David

PS -- example below illustrates the chunk of code, in case anyone is interested.

#!/usr/bin/env python
"""
 This program commandline.py illustrates a command-line reader   (David MacKay, 
license: GPL)
 that works a little like perl's
eval "\$$1=\$2" while @ARGV && $ARGV[0]=~ /^(\w+)=(.*)/ && shift;
 usage: (all arguments are optional)
commandline.py -bits 5  -decode 1 -file pimple  -N 1
"""
import sys
def usage(name):
print "Usage: %s -variableName value" % name
sys.exit()

def main():
## Define DEFAULTS that can be overridden on the command line
decode=0## are we decoding?
verbose=0   ## verbose output?
bits=7  ## how big are the blocks? 
N = 1   ## What is the file length?
file="blah" ## file name string
## End defaults

## Command-line reader:  Reads pairs of the form
## "-variableName value"
##   and sets  variableName=value. Gives error if this 
syntax is violated.
while ( len(sys.argv) > 1 ):
if ( sys.argv[1][0] == "-" ):
name = sys.argv.pop(1)
name = name[1:len(name)] 
if( len(sys.argv) <= 1 ): 
print >> sys.stderr, "could not get value for name ", name
usage(sys.argv[0])
else:
value = sys.argv.pop(1)
# here, we should assert that this variable exists!
command = "ntype = type(%s)" % (name)   # find type of this 
variable 
exec command
# convert value to the right type
command = "%s = ntype(%s) # %s" % ( name,`value`, str(ntype) )
if verbose:
print >> sys.stderr , "setting value:", command
exec command
else:
usage(sys.argv[0])
## End of command-line reader

## defaults that cannot be overridden on command line
securityLevel = 1
## end defaults

## Main program starts here

print >> sys.stderr, "  N =",N,"  bits =",bits, \
  "   file = ",file,  "   decode = ", decode

if __name__ == '__main__':main()



-- 
--
David J.C. MacKay [EMAIL PROTECTED] 787 9336
  http://www.aims.ac.za/~mackay/
-- 
http://mail.python.org/mailman/listinfo/python-list