Skip to content

Commit f980b2b

Browse files
martin-martinCopilotbzaczynski
authored
Add supporting code for Python Optional Arguments tutorial (#702)
* Add supporting code * Apply suggestions from code review Co-authored-by: Copilot <[email protected]> * Rename files * Final QA --------- Co-authored-by: Copilot <[email protected]> Co-authored-by: Bartosz Zaczyński <[email protected]>
1 parent ddcd360 commit f980b2b

File tree

4 files changed

+134
-0
lines changed

4 files changed

+134
-0
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Using Python Optional Arguments When Defining Functions
2+
3+
This folder contains accompanying code to the Real Python tutorial on [Using Python Optional Arguments When Defining Functions](https://realpython.com/python-optional-arguments/).
4+
5+
You can read each file and its comments, and run the files to see the code's output.
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
"""
2+
Demonstrates why using a mutable default (like {}) is a bad idea.
3+
4+
This mirrors the tutorial's buggy example so you can reproduce the issue.
5+
Run this file directly to see both variables share the same underlying dict.
6+
"""
7+
8+
9+
def add_item(item_name, quantity, shopping_list={}):
10+
# BAD: the default dict is created once and reused
11+
if item_name in shopping_list:
12+
shopping_list[item_name] += quantity
13+
else:
14+
shopping_list[item_name] = quantity
15+
return shopping_list
16+
17+
18+
clothes_shop_list = add_item("Shirt", 3) # Uses the shared default dict
19+
electronics_store_list = add_item("USB cable", 1) # Same shared dict!
20+
21+
print("clothes_shop_list:")
22+
for k, v in clothes_shop_list.items():
23+
print(f"{v}x {k}")
24+
25+
print("\nelectronics_store_list:")
26+
for k, v in electronics_store_list.items():
27+
print(f"{v}x {k}")
28+
29+
print(
30+
"\nNote how both lists contain the same combined items "
31+
"due to the shared default."
32+
)
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
"""
2+
Optional arguments in Python — consolidated, runnable examples.
3+
4+
This module collects the tutorial's final, good-practice implementations:
5+
6+
- show_list(shopping_list, include_quantities=True)
7+
- add_item(item_name, quantity, shopping_list=None)
8+
- add_items_args(shopping_list, *item_names)
9+
- add_items_kwargs(shopping_list, **things_to_buy)
10+
11+
Run the module directly to see a short demo.
12+
"""
13+
14+
15+
def show_list(shopping_list, include_quantities=True):
16+
for item_name, quantity in shopping_list.items():
17+
if include_quantities:
18+
print(f"{quantity}x {item_name}")
19+
else:
20+
print(item_name)
21+
print()
22+
23+
24+
def add_item(item_name, quantity, shopping_list=None):
25+
"""Add (or increment) an item in a list using the safe 'None' default."""
26+
if shopping_list is None:
27+
shopping_list = {}
28+
if item_name in shopping_list:
29+
shopping_list[item_name] += quantity
30+
else:
31+
shopping_list[item_name] = quantity
32+
return shopping_list
33+
34+
35+
def add_items_args(shopping_list, *item_names):
36+
"""Add any number of item names with default quantity 1 using *args."""
37+
for item_name in item_names:
38+
if item_name in shopping_list:
39+
shopping_list[item_name] += 1
40+
else:
41+
shopping_list[item_name] = 1
42+
return shopping_list
43+
44+
45+
def add_items_kwargs(shopping_list, **things_to_buy):
46+
"""Add any number of items with explicit quantities using **kwargs."""
47+
for item_name, quantity in things_to_buy.items():
48+
if item_name in shopping_list:
49+
shopping_list[item_name] += quantity
50+
else:
51+
shopping_list[item_name] = quantity
52+
return shopping_list
53+
54+
55+
# --- Using required + optional parameters (safe default pattern) ---
56+
hardware_store_list = {}
57+
hardware_store_list = add_item("Nails", 1, hardware_store_list)
58+
hardware_store_list = add_item("Screwdriver", 1, hardware_store_list)
59+
hardware_store_list = add_item("Glue", 3, hardware_store_list)
60+
61+
supermarket_list = {}
62+
supermarket_list = add_item("Bread", 1, supermarket_list)
63+
supermarket_list = add_item("Milk", 2, supermarket_list)
64+
65+
show_list(hardware_store_list) # With quantities
66+
show_list(supermarket_list, False) # Names only
67+
68+
# Create new lists on the fly by omitting shopping_list
69+
clothes_shop_list = add_item(
70+
"Shirt", 3
71+
) # New dict created inside the function
72+
electronics_store_list = add_item("USB cable", 1) # New dict created again
73+
show_list(clothes_shop_list)
74+
show_list(electronics_store_list)
75+
76+
# --- Using *args to add many items at once (defaults quantity to 1) ---
77+
multi_add_list = {}
78+
multi_add_list = add_items_args(
79+
multi_add_list, "Coffee", "Tea", "Cake", "Bread"
80+
)
81+
show_list(multi_add_list)
82+
83+
# --- Using **kwargs to add items with explicit quantities ---
84+
kw_list = {}
85+
kw_list = add_items_kwargs(kw_list, coffee=1, tea=2, cake=1, bread=3)
86+
show_list(kw_list)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
"""
2+
Unpacking operator demo to support the *args discussion.
3+
"""
4+
5+
some_items = ["Coffee", "Tea", "Cake", "Bread"]
6+
7+
print("Passing the list as a single argument:")
8+
print(some_items) # -> ['Coffee', 'Tea', 'Cake', 'Bread']
9+
10+
print("\nUnpacking the list with *some_items:")
11+
print(*some_items) # -> Coffee Tea Cake Bread

0 commit comments

Comments
 (0)