Argument traps: keywords, mutables, extras

A default list that is created once will keep growing across calls — a famous trap. Keyword calls document order. *args/**kwargs collect extras on a laptop; here you pass a list or a dict on purpose.

!

Broken form input

Check values before you calculate.

You will be able to

  • Call with keywords when order would confuse a clerk (amount=, rate=)
  • Avoid a mutable default — pass CONFIG or a new list each time
  • Treat extra UPI charges as a list you pass (*args on a laptop)

Keywords document order; defaults should be boring

add_gst(200, 18) is short. add_gst(amount=200, rate=18) is what you write when the next intern might swap the numbers. On a laptop, defaults like rate=18 are evaluated once, when def runs — not on every call. That is fine for an integer. It is a famous trap for a list or a dict: def collect(row, bucket=[]) reuses the same bucket across calls and the list keeps growing. You will not put a list in a default here. You will pass CONFIG, or pass a fresh list the caller owns.

If you need “optional extras”, pass extras as a list. On a laptop, *args collects leftover positional arguments into a tuple. The idea is the same: one name for a bundle of extra numbers, loop them.

**kwargs is a dict you passed on purpose

Laptop **kwargs gathers leftover keywords. This sandbox has no **. If a kiosk wants college= and gst=, pass a CONFIG dict. Do not invent a second way to hide globals.

The mutable-default bug shows up in internships as “the second student somehow already has yesterday’s attendance.” Defaults are not a reset button. Construct a new list inside the function, or take CONFIG from the caller.

Laptop: do not use a mutable default

def add_gst(amount, rate=18):
    return amount * (100 + rate) / 100

print(add_gst(100))
print(add_gst(amount=100, rate=0))

# def collect(item, bucket=[]):  # trap: one list for all calls
#     bucket.append(item)
#     return bucket

Words that matter

Keyword argument
name=value at the call — order is documented.
Mutable default
A list/dict default created once — later calls share it.
*args (laptop)
Extra positional values collected as a sequence — here, pass a list.

Common mistakes

Avoid: def notes(row, acc=[]) and wondering why the third call still has the first two rows.

Do this: Pass CONFIG, or build a new list inside the function each call.

Run it step by step

Each box is a real program. Press Run, change a number, Run again — the output must follow your code.

1. Step 1 — names in the def, values in order

On a laptop you may write amount=200, rate=18. Here the order matches the def: 200 then 18 is 236.

Python sandboxlesson://workspace
console

Edit the example, press Run, then Build if you want a compile check.

build

Press Build to compile.

2. Step 2 — extras as a list, not a growing default

CONFIG holds gst. Extra UPI amounts are passed in. Total 150.

Python sandboxlesson://workspace
console

Edit the example, press Run, then Build if you want a compile check.

build

Press Build to compile.

Example program — Fresh keepers every call

The empty list is created inside, not in the def line.

Python sandboxlesson://workspace
console

Edit the example, press Run, then Build if you want a compile check.

build

Press Build to compile.

Your turn — Sum the extra charges

total(parts) sums the list. Print total([50, 80, 20]) so 150 appears.

Python sandboxlesson://workspace
console

Edit the example, press Run, then Build if you want a compile check.

build

Press Build to compile.

Self-assessment

Check your understanding before you mark the lesson complete.

1. A mutable default argument is dangerous because…
2. *args on a laptop is closest to…

Progress is stored in a browser cookie on this device.