[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