Coverage for /usr/lib/python3/dist-packages/mpmath/usertools.py: 5%
42 statements
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-14 15:55 +0200
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-14 15:55 +0200
2def monitor(f, input='print', output='print'):
3 """
4 Returns a wrapped copy of *f* that monitors evaluation by calling
5 *input* with every input (*args*, *kwargs*) passed to *f* and
6 *output* with every value returned from *f*. The default action
7 (specify using the special string value ``'print'``) is to print
8 inputs and outputs to stdout, along with the total evaluation
9 count::
11 >>> from mpmath import *
12 >>> mp.dps = 5; mp.pretty = False
13 >>> diff(monitor(exp), 1) # diff will eval f(x-h) and f(x+h)
14 in 0 (mpf('0.99999999906867742538452148'),) {}
15 out 0 mpf('2.7182818259274480055282064')
16 in 1 (mpf('1.0000000009313225746154785'),) {}
17 out 1 mpf('2.7182818309906424675501024')
18 mpf('2.7182808')
20 To disable either the input or the output handler, you may
21 pass *None* as argument.
23 Custom input and output handlers may be used e.g. to store
24 results for later analysis::
26 >>> mp.dps = 15
27 >>> input = []
28 >>> output = []
29 >>> findroot(monitor(sin, input.append, output.append), 3.0)
30 mpf('3.1415926535897932')
31 >>> len(input) # Count number of evaluations
32 9
33 >>> print(input[3]); print(output[3])
34 ((mpf('3.1415076583334066'),), {})
35 8.49952562843408e-5
36 >>> print(input[4]); print(output[4])
37 ((mpf('3.1415928201669122'),), {})
38 -1.66577118985331e-7
40 """
41 if not input:
42 input = lambda v: None
43 elif input == 'print':
44 incount = [0]
45 def input(value):
46 args, kwargs = value
47 print("in %s %r %r" % (incount[0], args, kwargs))
48 incount[0] += 1
49 if not output:
50 output = lambda v: None
51 elif output == 'print':
52 outcount = [0]
53 def output(value):
54 print("out %s %r" % (outcount[0], value))
55 outcount[0] += 1
56 def f_monitored(*args, **kwargs):
57 input((args, kwargs))
58 v = f(*args, **kwargs)
59 output(v)
60 return v
61 return f_monitored
63def timing(f, *args, **kwargs):
64 """
65 Returns time elapsed for evaluating ``f()``. Optionally arguments
66 may be passed to time the execution of ``f(*args, **kwargs)``.
68 If the first call is very quick, ``f`` is called
69 repeatedly and the best time is returned.
70 """
71 once = kwargs.get('once')
72 if 'once' in kwargs:
73 del kwargs['once']
74 if args or kwargs:
75 if len(args) == 1 and not kwargs:
76 arg = args[0]
77 g = lambda: f(arg)
78 else:
79 g = lambda: f(*args, **kwargs)
80 else:
81 g = f
82 from timeit import default_timer as clock
83 t1=clock(); v=g(); t2=clock(); t=t2-t1
84 if t > 0.05 or once:
85 return t
86 for i in range(3):
87 t1=clock();
88 # Evaluate multiple times because the timer function
89 # has a significant overhead
90 g();g();g();g();g();g();g();g();g();g()
91 t2=clock()
92 t=min(t,(t2-t1)/10)
93 return t