def indicate(func): def wrapper(*args, **kwargs): print("=" * 15) print("Taken arguments:", *args, kwargs) result = func(*args, **kwargs) print("=" * 15) return result return wrapper @indicate def avg_two(a, b): """Calculate the average of two numbers""" return round((a + b) / 2, 1) @indicate def avg_three(a, b, c): """Calculate the average of three numbers""" return round((a + b + c) / 3, 1) @indicate def avg_many_kwargs(**kwargs): """Calculate the average of multiple numbers in a dictionary""" keys = 0 total = 0 for value in kwargs.values(): keys += 1 total += value return round(total / keys, 1) print("Returned:", avg_two(14, 21), "\n") print("Returned:", avg_three(225, 12, 11), "\n") print("Returned:", avg_many_kwargs(first=51, second=11, third=47, fourth=93)) ''' How this code works: This code defines a decorator indicate and three functions avg_two, avg_three, and avg_many_kwargs , each decorated with indicate. Here's a brief description of each component: Decorator indicate(func) function: - Adds functionality to print arguments and a separator before and after executing a function. - wrapper takes arguments *args and **kwargs and pass them to the func call. - The *args allows the wrapper() function to accept any number of positional arguments as a tuple. - The **kwargs allows the wrapper() function to accept any number of keyword arguments as a dictionary. The @indicate decorator is applied to three functions: - avg_two(a, b): Calculates and returns the average of two numbers, displaying additional information due to the decorator. - avg_three(a, b, c): Computes the average of three numbers, with additional prints from the decorator. - avg_many_kwargs(**kwargs): Finds the average of multiple numbers passed as keyword arguments, also showing argument details through the decorator. '''