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

1 

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:: 

10 

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') 

19 

20 To disable either the input or the output handler, you may 

21 pass *None* as argument. 

22 

23 Custom input and output handlers may be used e.g. to store 

24 results for later analysis:: 

25 

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 

39 

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 

62 

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)``. 

67 

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