easy +10 pts

Print Args Decorator

Create a decorator that logs function calls with their arguments and returns the result.

Write a decorator `print_args` that, when applied to a function, prints a line to standard output in the exact format: `Calling <func_name> with args=<args_tuple> kwargs=<kwargs_dict>` where `<func_name>` is the name of the decorated function, `<args_tuple>` is the positional arguments as a tuple (in the order provided), and `<kwargs_dict>` is the keyword arguments as a dictionary (in the order provided). After printing, the decorator must call the original function and return its result unchanged. The decorated function's `__name__` should remain the original function's name (use `functools.wraps`). Implement the function: ```python def print_args(func): ... ``` Then define the following decorated functions as shown: ```python @print_args def add(a, b=0): return a + b @print_args def greet(name="Alice"): return "Hi, " + name + "!" @print_args def no_args(): return 42 @print_args def concat(*parts, sep="-"): return sep.join(parts) ``` Note: The printing must happen exactly once per call. Do not modify the function's behavior otherwise. Example usage: ```python add(1, 2) # prints 'Calling add with args=(1, 2) kwargs={}' and returns 3 add(1) # prints 'Calling add with args=(1,) kwargs={}' and returns 1 add(1, b=3) # prints 'Calling add with args=(1,) kwargs={\'b\': 3}' and returns 4 greet() # prints 'Calling greet with args=() kwargs={}' and returns 'Hi, Alice!' greet(name="Bob") # prints 'Calling greet with args=() kwargs={\'name\': \'Bob\'}' and returns 'Hi, Bob!' no_args() # prints 'Calling no_args with args=() kwargs={}' and returns 42 concat("a", "b", sep="-") # prints 'Calling concat with args=(\'a\', \'b\') kwargs={\'sep\': \'-\'}' and returns 'a-b' ``` Your code should include the `print_args` decorator and the four decorated functions exactly as specified. The grader will import your solution and call these functions, checking return values. The printed lines are also checked for exact format.

Constraints

- The function `func` can take any number of positional and keyword arguments. - The decorator must work with any callable (including methods, but tests only use the four defined functions). - The printed line must be exactly as specified; no extra whitespace. - Use `functools.wraps` to preserve metadata. - The decorator must not alter the return value. - All four decorated functions (`add`, `greet`, `no_args`, `concat`) must be defined in your solution.

Example

>>> @print_args
>>> def add(a, b=0):
...     return a + b
>>> add(2, 3)
Calling add with args=(2, 3) kwargs={}
5
>>> add(2, b=4)
Calling add with args=(2,) kwargs={'b': 4}
6
>>> print(add.__name__)
add
>>> @print_args
>>> def greet(name="Alice"):
...     return "Hi, " + name + "!"
>>> greet()
Calling greet with args=() kwargs={}
'Hi, Alice!'
10 points ~10 min

Recent Submissions

No submissions yet — hit Run Tests to try!

Hints

Use functools.wraps to preserve the original function's metadata.
Inside the wrapper, print the required line using func.__name__, args, and kwargs.
The wrapper must return the result of func(*args, **kwargs).
Make sure all four decorated functions are defined exactly as specified.
Python 3
All tests passed!
Test Results
Press Ctrl+Enter or click Run Tests to execute your code.