[Tutor] A slight bug in IDLE
Dave Angel
davea at davea.name
Sun Jul 14 07:16:54 CEST 2013
On 07/14/2013 12:37 AM, Jim Mooney wrote:
> On 13 July 2013 20:03, Steven D'Aprano <steve at pearwood.info> wrote:
>
>>
>> I don't understand that last sentence.
>
>
> Ah, I can be marvelously unclear. I keep forgetting telepathy only works
> on my home planet ;')
You still have done nothing to explain the "last sentence." You obscure
that fact by not even keeping the context as to what the sentence was.
Repeating it for your edification, and our mystification:
"""Generators are one-off and input
is one-off, so they match well for testing, for instance.
"""
> I wiped everything out to start fresh with Py27, so this is just a very
> simple example of what worked in sending a few million test integers to my
> numbers-to-name program, which normally took typed input. The real test
> program used randoms to go up to the decillions and a straight count to go
> into the quadrillions, for about 40 tests (before my CPU overheated, this
> being Arizona ;')
>
> No doubt there is a standard way to do this, but I wanted to test the
> numbers program quickly, without mooching all over the net, so I threw
> something like this together:
>
> # The module I import, inputter.py:
> #Using Python 2.7 on Win 7
>
> def inp():
> x = raw_input('type a number: ')
> return x
>
> def intest():
> if int(inp()) < 10:
> print('smallnum')
> else:
> print('bignum')
>
> def main():
> intest()
>
> if __name__ == '__main__':
> main()
>
>
> # The Test Program, test.py that imports the module above:
> # Using Python 2.7 on Win 7
>
> import inputter
>
> x = (x for x in xrange(8,13)) # much bigger, and sometimes random, in the
> real test program
>
> def testfunc(): # This is where my typed input is replaced
> return next(x)
>
> inputter.inp = testfunc
That's monkey-patching. You're reaching inside the module and modifying
it. That's fine since you wrote both of them, but it makes things quite
hard to debug in more complex cases, and especially if you didn't write
the target module.
>
> for cnt in range(0,5):
> inputter.intest()
>
> '''result:
> smallnum
> smallnum
> bignum
> bignum
> bignum
> '''
One of the techniques the inputter module should have used is a
callback. You pass a function as a parameter, and it calls that
function. You can make a default value, of course, to make it easy to test.
Anyway, in inputter.py, you'd have
def intest(func=inp):
if int(func()) < 10:
print('smallnum')
else:
print('bignum')
and in your calling module, you would remove the monkeypatch, and just call
for cnt in range(0,5):
inputter.intest(testfunc)
The real problem I have is with your original code. It mixed input, and
calculations inside the same function, so you had to patch things up to
test it from outside. If you had refactored it as I suggested way back
then, and Steven suggested even better, this all would have been a
non-problem.
--
DaveA
More information about the Tutor
mailing list