From 632f0f583635d0480680fcbaa48f1867d76e397a Mon Sep 17 00:00:00 2001 From: Alex Moon Date: Fri, 29 Sep 2023 21:38:50 +0200 Subject: [PATCH 1/3] The decorator "cache" is created, tested and ready to work --- app/main.py | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 54 insertions(+), 3 deletions(-) diff --git a/app/main.py b/app/main.py index 68287892..02e0f6f6 100644 --- a/app/main.py +++ b/app/main.py @@ -1,6 +1,57 @@ -from typing import Callable +from typing import Callable, Any def cache(func: Callable) -> Callable: - # Write your code here - pass + """ + Decorator for caching results of functions with immutable arguments. + + The `cache` function is designed to automatically cache results of + functions with immutable (unchangeable) arguments. Each function + decorated with this decorator gets its own cache to store results. + In this decorator, the cache is reset with each new test suite. + + Args: + func (Callable): The function to be decorated. + + Returns: + Callable: The modified function that caches results based on + arguments. + + Examples: + @cache + def long_time_func(a: int, b: int, c: int) -> int: + return (a ** b ** c) % (a * c) + result = long_time_func(2, 3, 4) # Computation is performed + # and result is cached + result = long_time_func(2, 3, 4) # Result is retrieved from + # cache, computation is not + # repeated + + Note: + This decorator supports caching results for functions with + arguments that are immutable types, such as int, float, str, + tuple, bool, and NoneType. The results are stored in memory + and used for subsequent calls to the function with the same + arguments. + """ + cached_data = {} + immutable_type = (int, float, str, tuple, bool, type(None)) + + def argument_based_cacher(*args) -> Any: + nonlocal cached_data + if all([isinstance(variable, immutable_type) for variable in args]): + func_key = tuple(args) + if func.__name__ not in cached_data.keys(): + cached_data[func.__name__] = {} + if func_key in cached_data[func.__name__]: + print("Getting from cache") + return cached_data[func.__name__][func_key] + else: + print("Calculating new result") + func_result = func(*args) + cached_data[func.__name__][func_key] = func_result + return func_result + else: + print("Calculating new result") + return func(*args) + return argument_based_cacher From fe67f54d9801f4914455a1b74742a0d6ee4c6015 Mon Sep 17 00:00:00 2001 From: Alex Moon Date: Sat, 30 Sep 2023 11:40:36 +0200 Subject: [PATCH 2/3] Removed unnecessary "else", and docstring --- app/main.py | 44 +++++--------------------------------------- 1 file changed, 5 insertions(+), 39 deletions(-) diff --git a/app/main.py b/app/main.py index 02e0f6f6..c31d4335 100644 --- a/app/main.py +++ b/app/main.py @@ -2,38 +2,6 @@ def cache(func: Callable) -> Callable: - """ - Decorator for caching results of functions with immutable arguments. - - The `cache` function is designed to automatically cache results of - functions with immutable (unchangeable) arguments. Each function - decorated with this decorator gets its own cache to store results. - In this decorator, the cache is reset with each new test suite. - - Args: - func (Callable): The function to be decorated. - - Returns: - Callable: The modified function that caches results based on - arguments. - - Examples: - @cache - def long_time_func(a: int, b: int, c: int) -> int: - return (a ** b ** c) % (a * c) - result = long_time_func(2, 3, 4) # Computation is performed - # and result is cached - result = long_time_func(2, 3, 4) # Result is retrieved from - # cache, computation is not - # repeated - - Note: - This decorator supports caching results for functions with - arguments that are immutable types, such as int, float, str, - tuple, bool, and NoneType. The results are stored in memory - and used for subsequent calls to the function with the same - arguments. - """ cached_data = {} immutable_type = (int, float, str, tuple, bool, type(None)) @@ -46,12 +14,10 @@ def argument_based_cacher(*args) -> Any: if func_key in cached_data[func.__name__]: print("Getting from cache") return cached_data[func.__name__][func_key] - else: - print("Calculating new result") - func_result = func(*args) - cached_data[func.__name__][func_key] = func_result - return func_result - else: print("Calculating new result") - return func(*args) + func_result = func(*args) + cached_data[func.__name__][func_key] = func_result + return func_result + print("Calculating new result") + return func(*args) return argument_based_cacher From 8def2493fd1a6c42a7f89ac55a4a4cdcadd2fc4f Mon Sep 17 00:00:00 2001 From: Alex Moon Date: Mon, 2 Oct 2023 08:17:40 +0200 Subject: [PATCH 3/3] Removed redundant code. --- app/main.py | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/app/main.py b/app/main.py index c31d4335..bd29fa1d 100644 --- a/app/main.py +++ b/app/main.py @@ -3,21 +3,15 @@ def cache(func: Callable) -> Callable: cached_data = {} - immutable_type = (int, float, str, tuple, bool, type(None)) def argument_based_cacher(*args) -> Any: - nonlocal cached_data - if all([isinstance(variable, immutable_type) for variable in args]): - func_key = tuple(args) - if func.__name__ not in cached_data.keys(): - cached_data[func.__name__] = {} - if func_key in cached_data[func.__name__]: - print("Getting from cache") - return cached_data[func.__name__][func_key] - print("Calculating new result") - func_result = func(*args) - cached_data[func.__name__][func_key] = func_result - return func_result + if func.__name__ not in cached_data.keys(): + cached_data[func.__name__] = {} + if args in cached_data[func.__name__]: + print("Getting from cache") + return cached_data[func.__name__][args] print("Calculating new result") - return func(*args) + func_result = func(*args) + cached_data[func.__name__][args] = func_result + return func_result return argument_based_cacher