code: def memoize(fun):
      
      @functools.wraps(fun)
      def wrapper(*args, **kwargs):
          key = (args, frozenset(sorted(kwargs.items())))
          try:
              return cache[key]
          except KeyError:
              ret = cache[key] = fun(*args, **kwargs)
              return ret
  
      def cache_clear():
          """Clear cache."""
          cache.clear()
  
      cache = {}
      wrapper.cache_clear = cache_clear
      return wrapper
docs: A simple memoize decorator for functions supporting (hashable)
      positional arguments.
      It also provides a cache_clear() function for clearing the cache:
  
      >>> @memoize
      ... def foo()
      ...     return 1
          ...
      >>> foo()
      1
      >>> foo.cache_clear()
      >>>