import math
def caching(func):
cache = {}
def wrapped_func(*args):
argstr = '({})'.format(', '.join(map(str, args)))
if args not in cache:
print(f'> calculating {func.__name__}{argstr}')
cache[args] = func(*args)
else:
print(f'> reusing cached result for {func.__name__}{argstr}')
return cache[args]
return wrapped_func
@caching
def my_multiply(x, y):
return x * y
@caching
def my_divide(x, y):
return x / y
@caching
def my_hypot(a, b):
return math.sqrt(a * a + b * b)
print(my_multiply(2, 2))
print(my_divide(2, 2))
print(my_multiply(2, 2))
print(my_divide(2, 2))
print(my_hypot(2, 3))
print(my_divide(2, 3))
print(my_hypot(2, 3))
print(my_hypot(3, 3))
aW1wb3J0IG1hdGgKCmRlZiBjYWNoaW5nKGZ1bmMpOgogICAgY2FjaGUgPSB7fQogICAgZGVmIHdyYXBwZWRfZnVuYygqYXJncyk6CiAgICAgICAgYXJnc3RyID0gJyh7fSknLmZvcm1hdCgnLCAnLmpvaW4obWFwKHN0ciwgYXJncykpKQogICAgICAgIGlmIGFyZ3Mgbm90IGluIGNhY2hlOgogICAgICAgICAgICBwcmludChmJz4gY2FsY3VsYXRpbmcge2Z1bmMuX19uYW1lX199e2FyZ3N0cn0nKQogICAgICAgICAgICBjYWNoZVthcmdzXSA9IGZ1bmMoKmFyZ3MpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcHJpbnQoZic+IHJldXNpbmcgY2FjaGVkIHJlc3VsdCBmb3Ige2Z1bmMuX19uYW1lX199e2FyZ3N0cn0nKQogICAgICAgIHJldHVybiBjYWNoZVthcmdzXQogICAgcmV0dXJuIHdyYXBwZWRfZnVuYwoKQGNhY2hpbmcKZGVmIG15X211bHRpcGx5KHgsIHkpOgogICAgcmV0dXJuIHggKiB5CgpAY2FjaGluZwpkZWYgbXlfZGl2aWRlKHgsIHkpOgogICAgcmV0dXJuIHggLyB5CgpAY2FjaGluZwpkZWYgbXlfaHlwb3QoYSwgYik6CiAgICByZXR1cm4gbWF0aC5zcXJ0KGEgKiBhICsgYiAqIGIpCgpwcmludChteV9tdWx0aXBseSgyLCAyKSkKcHJpbnQobXlfZGl2aWRlKDIsIDIpKQpwcmludChteV9tdWx0aXBseSgyLCAyKSkKcHJpbnQobXlfZGl2aWRlKDIsIDIpKQpwcmludChteV9oeXBvdCgyLCAzKSkKcHJpbnQobXlfZGl2aWRlKDIsIDMpKQpwcmludChteV9oeXBvdCgyLCAzKSkKcHJpbnQobXlfaHlwb3QoMywgMykp
> calculating my_multiply(2, 2)
4
> calculating my_divide(2, 2)
1.0
> reusing cached result for my_multiply(2, 2)
4
> reusing cached result for my_divide(2, 2)
1.0
> calculating my_hypot(2, 3)
3.605551275463989
> calculating my_divide(2, 3)
0.6666666666666666
> reusing cached result for my_hypot(2, 3)
3.605551275463989
> calculating my_hypot(3, 3)
4.242640687119285