Midterm Review: Python Problem Sets 2

Problem 1: Args and Kwargs Output

Given the following code, what will be the output?

def func(*args, **kwargs):
    print(args)
    print(kwargs)
 
func(1, 2, 3, a=4, b=5)
Solution

Output:

(1, 2, 3)
{'a': 4, 'b': 5}

Explanation: *args captures all positional arguments as a tuple (1, 2, 3). **kwargs captures all keyword arguments as a dictionary {'a': 4, 'b': 5}.

Problem 2: Parameter Passing

Analyze the following code and explain the output:

def func(a, *args, b):
    print(a, args, b)
 
func(1, 2, 3, 4)
Solution

This call will result in an error:

func() missing 1 required keyword-only argument: 'b'

Explanation: The parameter b comes after *args, making it a keyword-only parameter, even if it is not explicitly declared with a default assignment. It must be provided explicitly as a keyword argument when called. The correct call would be: func(1, 2, 3, b=some_value), eg. func(1, 2, 3, b=4).

Problem 3: Parameter Passing

Determine whether the following function definition is valid. If not, explain why:

def func(a, b, /, c, *, d):
    return a + b + c + d
Solution

Yes, this function definition is valid.

Explanation: The / indicates that parameters a and b are positional-only (can only be passed by position, not as keywords). The * indicates that parameter d is keyword-only (must be passed as a keyword argument). Parameter c is positional-or-keyword (can be passed either way). This is a valid function signature.

Problem 4: Parameter Passing

Is there an error in any of the calls to func? Why? If not, what is the output for each call to func?

def func(a, /, b, *, c):
    return a + b + c
 
func(1, 2, 3)
func(a=1, b=3, c=3)
func(1, b=2, c=3)
func(1, 2, c=3)
Solution

Call 1: func(1, 2, 3)ERROR: func() takes 2 positional arguments but 3 were given. The third argument provided is positional, but the function defines c as keyword-only.

Call 2: func(a=1, b=3, c=3)ERROR: func() got some positional-only arguments passed as keyword arguments: 'a'. Parameter a is defined as positional-only and cannot be passed as a keyword.

Call 3: func(1, b=2, c=3)Output: 6. This is correct: a=1 (positional-only), b=2 (positional-or-keyword), c=3 (keyword-only).

Call 4: func(1, 2, c=3)Output: 6. This is also correct: a=1 (positional-only), b=2 (positional-or-keyword), c=3 (keyword-only).

Problem 5: Parameter Passing

Analyze the following code and explain the behavior:

def func(a, b, /):
    return a + b
 
print(func(1, 2))
print(func(a=1, b=2))
Solution

First call: func(1, 2)Output: 3. This works because both arguments are passed positionally.

Second call: func(a=1, b=2)ERROR: func() got some positional-only arguments passed as keyword arguments: 'a', 'b'. Since both parameters are positional-only (marked with /), they cannot be passed as keyword arguments.

Problem 6: Parameter Passing

Determine if the following function works as expected. Explain:

def func(*, a, b):
    return a * b
 
print(func(a=3, b=4))
print(func(3, 4))
Solution

First call: func(a=3, b=4)Output: 12. This works because both arguments are passed as keyword arguments, which is required.

Second call: func(3, 4)ERROR: func() takes 0 positional arguments but 2 were given. Since both parameters are keyword-only (there’s nothing before the *), they cannot be passed positionally.

Problem 7: Default Parameter Values

What is the output of the following code? Explain:

def func(x, y=10):
    return x * y
 
print(func(5))
print(func(5, 20))
Solution

First call: func(5)Output: 50. Since y has a default value of 10, when not provided, it uses 10. So 5 * 10 = 50.

Second call: func(5, 20)Output: 100. The value 20 is passed for y, so 5 * 20 = 100.

Problem 8: Parameter Order

Does the following function definition contain any errors? If so, describe them:

def func(a=1, b):
    return a + b
Solution

Yes, this function definition contains a SyntaxError: non-default argument follows default argument.

Explanation: In Python, parameters with default values must come after parameters without default values. Parameter a has a default value (1), but parameter b does not. This violates the rule. The correct order would be:

def func(b, a=1):
    return a + b

Problem 9: Mutable Default Argument Pitfall

Explain the behavior of the following code. Is there any potential pitfall associated with having a keyword argument being assigned a mutable value as a default?

def func(a, mylist=[]):
    mylist.append(a)
    return mylist
 
print(func(1))
print(func(2))
Solution

Output:

[1]
[1, 2]

Explanation: This demonstrates the mutable default argument pitfall. Default arguments are created once when the function is defined, not each time it’s called. Since mylist=[] is a mutable object (a list), the same list object is reused across all function calls. When the function is called the first time, 1 is appended to the empty list, creating [1]. On the second call, the same list object is used (now containing [1]), and 2 is appended to it, resulting in [1, 2].

To avoid this pitfall, use None as the default and create a new list inside the function:

def func(a, mylist=None):
    if mylist is None:
        mylist = []
    mylist.append(a)
    return mylist