[Tutor] pylint(too-many-nested-blocks)
Cameron Simpson
cs at cskk.id.au
Tue Nov 30 21:19:22 EST 2021
On 01Dec2021 08:57, Phil <phillor9 at gmail.com> wrote:
>>Now is a good time pick-up the testing tool's feedback:
>>"understandable
>>and maintainable". It's not merely a matter of
>>"readability"/"understandability", but also maintainability - and that
>>of the objectives of the tool: "testability".
>
>I know that testing tools exist, however, I've always considered their
>use to be beyond the understanding of the neophyte especially this
>amateur programmer.
Doctest is pretty simple, though it lends itself mostly to pretty simple
tests. But its so handy for some things that I try to use it as examples
in the documentation.
Here's an example from my own personal kit. The function's got quite a
lot of if/else branches and is slightly hard to inspect for correctness.
But a doctest lets me at least run some simple examples I'm actually
expecting to use and verify that they get correct output.
That said, here's the function. The docstring is in MarkDown format and
get written to the module documentation. The doctests are the ">>> "
prefixed stuff, as in the Python interactive prompt.
# pylint: disable=redefined-outer-name
def strip_prefix_n(s, prefix, n=None):
''' Strip a leading `prefix` and numeric value `n` from the start of a
string. Return the remaining string, or the original string if the
prefix or numeric value do not match.
Parameters:
* `s`: the string to strip
* `prefix`: the prefix string which must appear at the start of `s`
* `n`: optional integer value;
if omitted any value will be accepted, otherwise the numeric
part must match `n`
Examples:
>>> strip_prefix_n('s03e01--', 's', 3)
'e01--'
>>> strip_prefix_n('s03e01--', 's', 4)
's03e01--'
>>> strip_prefix_n('s03e01--', 's')
'e01--'
'''
s0 = s
if prefix:
s = cutprefix(s, prefix)
if s is s0:
# no match, return unchanged
return s0
else:
s = s0
if not s or not s[0].isdigit():
# no following digits, return unchanged
return s0
if n is None:
# strip all following digits
s = s.lstrip(digits)
else:
# evaluate the numeric part
s = s.lstrip('0') # pylint: disable=no-member
if not s or not s[0].isdigit():
# all zeroes, leading value is 0
sn = 0
pos = 0
else:
pos = 1
slen = len(s)
while pos < slen and s[pos].isdigit():
pos += 1
sn = int(s[:pos])
if sn != n:
# wrong numeric value
return s0
s = s[pos:]
return s
So those lines are literally cut/paste from exercises in the interactive
prompt. To run the tests:
python3 -m doctest cs/lex.py
which runs all the doctests in the file. "doctest is part of the
standard library.
This basic level is great for simple assertions which verify basic
operation of your functions, particularly the cases which mattered to
you when you wrote them, and various simple corner cases.
There are more elaborate things, and I try to use them, but doctest is a
great first start, as so easy!
>>Earlier the idea of naming a chunk of code was mentioned.
>
>I find it difficult to come up with meaningful names for functions and
>even variables. I know that 'x' or 'y' is often a poor choice and I
>often leave them in place until I can think of something better. Often
>I don't and so they stay, and of course, I forget what they mean the
>next time I look at the code again.
Just regular nouns like "word", "vertex" etc are good basics. But don't
eschew the concise when it matters:
for i, vertex in vertices:
print("index", i, "has vertex", vertex)
Nothing wrong with "i" there!
Cheers,
Cameron Simpson <cs at cskk.id.au>
More information about the Tutor
mailing list