diff --git a/Week04/decorators_sefa_sagirli.py b/Week04/decorators_sefa_sagirli.py new file mode 100644 index 00000000..47db1c29 --- /dev/null +++ b/Week04/decorators_sefa_sagirli.py @@ -0,0 +1,32 @@ +import time +import tracemalloc + + +def performance(func): + """ + Measure the performance of the decorated function. + + The decorator keeps three statistics as its own attributes: + counter (number of calls), total_time (in seconds) and + total_mem (peak memory in bytes used by the calls). + """ + def wrapper(*args, **kwargs): + tracemalloc.start() + start_time = time.perf_counter() + try: + result = func(*args, **kwargs) + finally: + elapsed = time.perf_counter() - start_time + _, peak = tracemalloc.get_traced_memory() + tracemalloc.stop() + performance.counter += 1 + performance.total_time += elapsed + performance.total_mem += peak + return result + + return wrapper + + +performance.counter = 0 +performance.total_time = 0 +performance.total_mem = 0 diff --git a/Week04/functions_sefa_sagirli.py b/Week04/functions_sefa_sagirli.py new file mode 100644 index 00000000..59648e6c --- /dev/null +++ b/Week04/functions_sefa_sagirli.py @@ -0,0 +1,41 @@ +custom_power = lambda x=0, /, e=1: x ** e # noqa: E731 + + +def custom_equation(x: int = 0, y: int = 0, /, a: int = 1, b: int = 1, *, c: int = 1) -> float: + """ + Calculate the result of the equation (x**a + y**b) / c. + + :param x: The first base, positional-only, defaults to 0 + :type x: int + :param y: The second base, positional-only, defaults to 0 + :type y: int + :param a: The exponent of x, defaults to 1 + :type a: int + :param b: The exponent of y, defaults to 1 + :type b: int + :param c: The divisor, keyword-only, defaults to 1 + :type c: int + :raises TypeError: If any of the parameters is not an integer + :return: The result of (x**a + y**b) / c + :rtype: float + """ + for name, value in (("x", x), ("y", y), ("a", a), ("b", b), ("c", c)): + if not isinstance(value, int): + raise TypeError(f"{name} must be an integer") + return (x ** a + y ** b) / c + + +def fn_w_counter() -> (int, dict[str, int]): + """ + Count the total number of calls and the number of calls per caller. + + :return: The total number of calls and a dictionary of callers with their call counts + :rtype: tuple[int, dict[str, int]] + """ + if not hasattr(fn_w_counter, "total_calls"): + fn_w_counter.total_calls = 0 + fn_w_counter.callers = {} + caller = __name__ + fn_w_counter.total_calls += 1 + fn_w_counter.callers[caller] = fn_w_counter.callers.get(caller, 0) + 1 + return fn_w_counter.total_calls, fn_w_counter.callers