"""
Uses the same logcall function as decorators1.py does,
but uses it as a decorator of a user-defined function
instead of calling it directly
"""

def logcall(f):
    """A function-wrapping function:
    logcall(f) returns a function just like f
    except it prints its arguments and return values"""
    def logcall_wrapper(*args, **kargs):
        print(f.__name__,'arguments',args, kargs,)
        retval = f(*args, **kargs)
        print(f.__name__,'returns',retval)
        return retval
    # rename the wrapper; only matters for a few debugging tools
    logcall_wrapper.__name__ = 'logcall('+f.__name__+')'
    return logcall_wrapper

# @func before a function name means "after defining the function, replace it with func(itself)"
# i.e., this example is the same as 
#
# def compare(a,b):
#    ... # code here
# compare = logcall(compare)
#
# the @func line is called a "decorator"
@logcall
def compare(a,b):
    try:
        if a < b: return 'less'
        elif a == b: return 'same'
        else: return 'more'
    except TypeError as ex:
        return 'incomparable', str(ex)


print([compare(a,b) for a,b in zip(range(-2,3), range(-3,7,2))])
print(compare(b=3,a=None))
print(compare(1, b=-1))
print(compare.__name__)