When debugging, we often see print statements like these:
print x # easy to type, but no context
print \'x=\',x # more context, harder to type
12
x=
A simple example would be:
def debugPrint(*expr):
text = traceback.extract_stack()[-2][3]
begin = text.find('debugPrint(') + len('debugPrint(')
end = text.find(')',begin)
text=[name.strip() for name in text[begin:end].split(',')]
for t, e in text, expr:
print(str(t) + " = " + str(e))
Hope it helps!
I wrote the following to be able to type something like (at line 41 of file describe.py
):
describe('foo' + 'bar')
describe(numpy.zeros((2, 4)))
and see:
describe.py@41 describe('foo' + 'bar') = str(foobar) [len=6]
describe.py@42 describe(numpy.zeros((2, 4))) = ndarray(array([[0., 0., 0., 0.],
[0., 0., 0., 0.]])) [shape=(2, 4)]
Here's how:
# Print the line and filename, function call, the class, str representation and some other info
# Inspired by https://stackoverflow.com/a/8856387/5353461
import inspect
import re
def describe(arg):
frame = inspect.currentframe()
callerframeinfo = inspect.getframeinfo(frame.f_back)
try:
context = inspect.getframeinfo(frame.f_back).code_context
caller_lines = ''.join([line.strip() for line in context])
m = re.search(r'describe\s*\((.+?)\)$', caller_lines)
if m:
caller_lines = m.group(1)
position = str(callerframeinfo.filename) + "@" + str(callerframeinfo.lineno)
# Add additional info such as array shape or string length
additional = ''
if hasattr(arg, "shape"):
additional += "[shape={}]".format(arg.shape)
elif hasattr(arg, "__len__"): # shape includes length information
additional += "[len={}]".format(len(arg))
# Use str() representation if it is printable
str_arg = str(arg)
str_arg = str_arg if str_arg.isprintable() else repr(arg)
print(position, "describe(" + caller_lines + ") = ", end='')
print(arg.__class__.__name__ + "(" + str_arg + ")", additional)
else:
print("Describe: couldn't find caller context")
finally:
del frame
del callerframeinfo
https://gist.github.com/HaleTom/125f0c0b0a1fb4fbf4311e6aa763844b
Multiple variables (taking @Blender response one step further) :
def debug(variables, sep =''):
vars = variables.split(',')
for var in vars:
print(var, '=', repr(eval(var)), end = sep)
Example:
import bumpy as np
gPrimeLinear = lambda z: np.ones(np.array(z).size)*z
gPrimeSigmoid = lambda z: 1./(1+np.exp(-z))*(1-1./(1+np.exp(-z)))
gPrimeTanh = lambda z: 1- np.tanh(z)**2
z = np.array([ 0.2, 0.4, 0.1])
debug("z, gPrimeLinear(z), gPrimeSigmoid(z), gPrimeTanh(z)", '\n')
This returns:
> z = array([0.2, 0.4, 0.1])
> gPrimeLinear(z) = array([0.2, 0.4, 0.1])
> gPrimeSigmoid(z) = array([0.24751657, 0.24026075, 0.24937604])
> gPrimeTanh(z) = array([0.96104298, 0.85563879, 0.99006629])