[Tutor] doctest question

Albert-Jan Roskam fomcl at yahoo.com
Tue Nov 27 10:50:24 CET 2012


 
> On 27/11/12 08:06, Albert-Jan Roskam wrote:
>> Hi,
>> 
>> I am using doctest and I am struggling with newlines characters
>> (see below). One is the newline escape (backslash) for a long
>> dictionary definition. The other is an embedded \n in the output.
>> I used the +NORMALIZE_WHITESPACE directive. I also tried using a
>>   triple-quoted raw docstring. Any ideas?
> 
> Yes, quite a few.
> 
> Your following example is hard to understand and, as they say in
> English, "as clear as mud". It would help a lot if you laid out the
> example dictionary so that it was easier to read, and if you followed
> the standard convention to end the docstring with a single """ so
> that it separates the end of the docstring from the start of the code.

 
Ok, good idea. After all, "Readability counts"
 
 
> Function name "_setMultRespDefsEx" is not self-explanatory, or even
> *hint* at what the function is supposed to do. It appears to take a
> dictionary of stuff, and formats it as a string. It would be nice[1]
> if your docstring explained what sort of stuff.

But in my defense (a little bit, at least), this is a helper
function for another function that *does* have a good explanation/docstring.
I should mention that in this function's docstring though. You're right that I
could, at the very least, start by saying: 
"""
Helper function to set extended multiple response definitions (see function 'blaah' for further info)
 
<doctest stuff>"""
 
 
> The example given should be simple, not complex. If you must give a
> complex example, always give a simple example first.
> 
> Examples should be written for clarity, not as code golf. There is no
> prize for stuffing everything into one or two lines.
> 
> Doctext directives are not global to the docstring, they must appear
> on the same line as the doctest itself.

AHA! I missed that from the online documentation. Thank you.

 
> Take advantage of Python's implicit line continuation to avoid
> problems with backslash line continuations.
> 
> Doctesting anything to do with dictionaries is tricky, because you
> cannot rely on the order of a dict. There are a couple of different
> ways to solve that:
 
Huh? Although I am iterating over a dictionary (which is unordered),
the return value will, given a certain input, always be the same. Why 
is the 'unorderedness' relevant here?
 
 
> * the lazy solution: always use doctests on dicts with a single item;
> 
> * change the function to always process the dict in a known order;
> 
> * change the doctest to post-process the function result, e.g. pull
>   the string apart into separate lines, sort the lines, put it
>   back together.
> 
> 
> Here's my attempt:
> 
> 
> import doctest
> import copy
> 
> def _setMultRespDefsEx(multRespDefs):
>     """Format a dictionary of stuff as a string. Expects that 
> dict contains:
> 
>     {breakfast: {spam: foo, ham: bar} blah blah blah ...}  # or whatever
> 
>     >>> xdict = {'countedValue': '1', 
> 'firstVarIsLabel': True, 'label': '',
>     ...          'setType': 'E','varNames':  
> ['mevar1', 'mevar2', 'mevar3']}
>     >>> ydict = {'countedValue': 'Yes', 
> 'firstVarIsLabel': False,
>     ...          'label': 'Enhanced set with user specified 
> label',
>     ...          'setType': 'E', 'varNames': 
> ['mevar4', 'mevar5', 'mevar6']}
>     >>> adict = {'mesetx': xdict, 'mesety': ydict}
>     >>> print(_setMultRespDefsEx(adict))
>     $mesetx=E 11 1 1 0 mevar1 mevar2 mevar3
>     $mesety=E 1 3 Yes 38 Enhanced set with user specified label mevar4 mevar5 
> mevar6
> 
>     KNOWN BUGS:
> 
>         1) Sometimes this function returns a dict instead of a string.
>         2) The formatted string output is ambiguous.
> 
>     """
>     mrDefs = []  # "That's Mister Defs to you" :-)

 
;-)))
 
>     for setName, rest in sorted(multRespDefs.iteritems()):
>         if rest["setType"] != "E":
>             return {}
>         rest["setName"] = setName
>         v = int(rest["firstVarIsLabel"])
>         rest["firstVarIsLabel"] = v if v == 1 else ""
>         rest["valueLen"] = len(rest["countedValue"])
>         rest["lblLen"] = len(rest["label"])
>         rest["label"] = rest["label"]
>         rest["varNames"] = " 
> ".join(rest["varNames"])
>         mrDef =  "$%(setName)s=%(setType)s 1%(firstVarIsLabel)s 
> %(valueLen)s "
>         mrDef += "%(countedValue)s %(lblLen)s %(label)s %(varNames)s"
>         mrDefs.append((mrDef % rest).replace("  ", " "))
>     return "\n".join(mrDefs)
> 
> 
> 
> And running the doctest:
> 
> py> doctest.testmod()
> TestResults(failed=0, attempted=4)
> 
> 
> 
> 
> 
> [1] By "nice" I mean *essential*.
> 
> 
> -- Steven
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> http://mail.python.org/mailman/listinfo/tutor
> 


More information about the Tutor mailing list