← Back to Python series
🌱
Basic
CRUD · Iteration · Comprehension · Set Operations · Methods · Slicing · format() · f-strings · encode · def · return · Arguments · Defaults · Scope · Review · Integration · File persistence

Weeks 7–10 — Dictionaries & Sets · String Methods & Formatting · Functions · Basic Capstone: CLI To-Do App

Use dictionaries for key-value storage and sets for unique collections. Learn dict comprehensions, set algebra, and when to choose each structure. Strings are immutable sequences with a rich method library. Learn to slice, search, replace, split, join, and format text for real-world use. Functions let you name and reuse blocks of logic. Learn def, return, default arguments, keyword arguments, and variable scope (LEGB rule). Combine everything from weeks 1–9 into a full command-line to-do application with add, list, complete, and delete commands. Optionally persist tasks to a JSON file.

dictsethashcomprehensionstringf-stringformatsplitjoinregexfunctiondefreturnscopeargumentscapstoneprojectCLIJSONintegration
Duration
⏱ 2.5 hours + 2 hours + 2.5 hours + 3 hours
Level
📊 Beginner
Prerequisite
🎯 Week 6
OUTCOME
Build a word frequency counter using dictionaries / Write a text cleaning and analysis utility / Refactor a calculator into well-named functions with docstrings / A working CLI to-do app you can run from the terminal

What you'll learn

  • 1Create, read, update, and delete dictionary entries
  • 2Iterate over keys, values, and items
  • 3Build dict comprehensions
  • 4Perform union, intersection, and difference on sets
  • 5Know when to use dict vs list vs set
  • 6Use upper, lower, strip, replace, split, join
  • 7Format strings with f-strings and format()
  • 8Slice strings like lists
  • 9Check membership with in and startswith/endswith
  • 10Understand string immutability
  • 11Define and call functions with def
  • 12Return single and multiple values
  • 13Use positional, keyword, and default arguments
  • 14Understand the LEGB scope rule
  • 15Write docstrings to document functions
  • 16Integrate lists, dicts, functions, and loops in one project
  • 17Handle user input robustly with error messages
  • 18Save and load tasks from a JSON file
  • 19Structure code into well-named functions
  • 20Practice the full development loop: plan → code → test

Week 7 — Dictionaries & Sets

Use dictionaries for key-value storage and sets for unique collections. Learn dict comprehensions, set algebra, and when to choose each structure.

1. Dictionaries

Dictionaries store key-value pairs. Keys must be unique and hashable (usually strings or numbers).

python
person = {"name": "Alice", "age": 25, "city": "Seoul"}
print(person["name"])          # Alice
person["email"] = "a@ex.com"  # add
person["age"] = 26             # update
del person["city"]             # delete
print("age" in person)         # True
print(person.get("phone", "N/A"))  # N/A (safe access)

2. Iterating Dictionaries

python
scores = {"Alice": 95, "Bob": 82, "Charlie": 78}
for name in scores:            # keys
    print(name)
for score in scores.values():  # values
    print(score)
for name, score in scores.items():  # both
    print(f"{name}: {score}")

3. Sets

Sets hold unique, unordered items. Great for membership tests and set algebra.

python
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}
print(a | b)  # union:        {1,2,3,4,5,6}
print(a & b)  # intersection: {3,4}
print(a - b)  # difference:   {1,2}
print(a ^ b)  # symmetric diff: {1,2,5,6}

4. Dict Comprehension

python
# Square each number
squares = {n: n**2 for n in range(1, 6)}
print(squares)  # {1:1, 2:4, 3:9, 4:16, 5:25}

# Filter: only even keys
even = {k: v for k, v in squares.items() if k % 2 == 0}
print(even)  # {2:4, 4:16}

5. Common Mistakes

  1. dict[key] on a missing key → KeyError. Use dict.get(key, default) for safe access.
  2. Sets are unordered — don't rely on insertion order. Use a list if order matters.
  3. {} creates an empty dict, not a set. Use set() for an empty set.

Week 8 — String Methods & Formatting

Strings are immutable sequences with a rich method library. Learn to slice, search, replace, split, join, and format text for real-world use.

1. String Basics

python
s = "  Hello, World!  "
print(s.upper())         # "  HELLO, WORLD!  "
print(s.lower())         # "  hello, world!  "
print(s.strip())         # "Hello, World!"
print(s.strip().replace("World", "Python"))
print(len(s))            # 18
ℹ️

Strings are immutable — every method returns a new string; the original is unchanged.

2. Split & Join

python
csv = "Alice,Bob,Charlie,Diana"
names = csv.split(",")    # list of strings
print(names)              # ['Alice', 'Bob', ...]
joined = " | ".join(names)
print(joined)             # Alice | Bob | Charlie | Diana

3. String Formatting

python
name, score = "Alice", 92.5
# f-string (recommended)
print(f"{name} scored {score:.1f}")
# format()
print("{} scored {:.1f}".format(name, score))
# Width & alignment
print(f"{name:<10}|{score:>8.2f}")  # left|right aligned

4. Useful Methods

MethodExampleResult
find(sub)"hello".find("ll")2
count(sub)"banana".count("a")3
startswith(s)"hello".startswith("he")True
endswith(s)"hello".endswith("lo")True
isdigit()"123".isdigit()True
isalpha()"abc".isalpha()True
zfill(n)"42".zfill(5)"00042"

5. Common Mistakes

  1. Forgetting that strings are immutable: s.upper() doesn't change s — you must reassign: s = s.upper().
  2. split() with no argument splits on any whitespace and removes empty strings; split(' ') preserves them.
  3. "hello"[0] = 'H' → TypeError. Create a new string: 'H' + "hello"[1:].

Week 9 — Functions

Functions let you name and reuse blocks of logic. Learn def, return, default arguments, keyword arguments, and variable scope (LEGB rule).

1. Defining Functions

python
def greet(name):
    """Return a greeting string."""
    return f"Hello, {name}!"

print(greet("Alice"))   # Hello, Alice!
print(greet("Bob"))     # Hello, Bob!
💡

Always write a docstring (triple-quoted string right after def) to document what the function does.

2. Return Values

python
def divide(a, b):
    if b == 0:
        return None, "Division by zero"
    return a / b, None

result, error = divide(10, 2)
if error:
    print(error)
else:
    print(result)  # 5.0

3. Arguments

python
def power(base, exp=2):          # default argument
    return base ** exp

print(power(3))       # 9  (exp defaults to 2)
print(power(3, 3))    # 27
print(power(exp=3, base=2))  # keyword arg: 8

4. Scope (LEGB)

Python looks up variable names in this order: Local → Enclosing → Global → Built-in.

python
x = 10          # global

def func():
    x = 20      # local — does NOT change the global x
    print(x)    # 20

func()
print(x)        # 10

# To modify global x inside a function:
def func2():
    global x
    x = 99
func2()
print(x)        # 99

5. Common Mistakes

  1. A function without return returns None implicitly.
  2. Mutable default arguments (def f(lst=[])) are shared between calls — use def f(lst=None): lst = lst or [].
  3. Calling a function before defining it → NameError. Define first, call second.

Week 10 — Basic Capstone: CLI To-Do App

Combine everything from weeks 1–9 into a full command-line to-do application with add, list, complete, and delete commands. Optionally persist tasks to a JSON file.

1. Project Specification

  • Commands: add <title>, list, done <id>, delete <id>, quit
  • Each task: id (auto-increment), title, done (bool)
  • Persist tasks in tasks.json on disk
  • Show task count and completion stats on list

2. Architecture

  • load_tasks() / save_tasks() — JSON file I/O
  • add_task(tasks, title) — append new task dict
  • list_tasks(tasks) — print numbered table
  • mark_done(tasks, task_id) — find by id and set done=True
  • delete_task(tasks, task_id) — filter out by id
  • main() — REPL loop with command dispatch

3. Sample Session

text
Todo App — type 'help' for commands
> add Buy groceries
  [1] added.
> add Write report
  [2] added.
> list
  ID  Status  Title
  1   [ ]     Buy groceries
  2   [ ]     Write report
> done 1
  [1] marked as done.
> list
  ID  Status  Title
  1   [x]     Buy groceries
  2   [ ]     Write report
  Done: 1/2
> quit
  Bye!

4. Extension Challenges

  • Add a priority field (high/medium/low) and sort by priority on list
  • Add a due date field and highlight overdue tasks in red (colorama)
  • Add search <keyword> command to filter tasks

💻 Examples

Run these examples and check the output yourself.

01_phonebook.py— Phone book with CRUD
CODE
phonebook = {}
while True:
    cmd = input("add/lookup/delete/quit: ").strip()
    if cmd == "add":
        name = input("  Name: ")
        phone = input("  Phone: ")
        phonebook[name] = phone
        print(f"  Saved {name}.")
    elif cmd == "lookup":
        name = input("  Name: ")
        print(" ", phonebook.get(name, "Not found"))
    elif cmd == "delete":
        name = input("  Name: ")
        phonebook.pop(name, None)
    elif cmd == "quit":
        break
02_word_count.py— Word frequency counter
CODE
text = input("Enter a sentence: ").lower()
words = text.split()
freq = {}
for w in words:
    freq[w] = freq.get(w, 0) + 1
for word, count in sorted(freq.items(), key=lambda x: -x[1]):
    print(f"  {word}: {count}")
03_set_ops.py— Set algebra on two word lists
CODE
a = set("the cat sat on the mat".split())
b = set("the dog sat on the log".split())
print("Common words:  ", a & b)
print("Unique to A:   ", a - b)
print("All words:     ", a | b)
▶ Output
Common words:   {'the', 'on', 'sat'}
Unique to A:    {'cat', 'mat'}
All words:      {'the', 'on', 'sat', 'cat', 'mat', 'dog', 'log'}
01_string_methods.py— Chaining common string methods
CODE
raw = "  python is AWESOME!  "
cleaned = raw.strip().lower()
print(cleaned)
print(cleaned.count("is"))
print(cleaned.replace("python", "coding"))
▶ Output
python is awesome!
1
coding is awesome!
02_csv_parser.py— Parse CSV line into named fields
CODE
line = "Alice,25,Seoul,Developer"
fields = line.split(",")
labels = ["Name", "Age", "City", "Job"]
for label, value in zip(labels, fields):
    print(f"{label:6}: {value}")
▶ Output
Name  : Alice
Age   : 25
City  : Seoul
Job   : Developer
03_format.py— Table formatting with f-strings
CODE
students = [("Alice", 95), ("Bob", 82), ("Charlie", 71)]
print(f"{'Name':<10} {'Score':>6}")
print("-" * 18)
for name, score in students:
    print(f"{name:<10} {score:>6}")
▶ Output
Name        Score
------------------
Alice           95
Bob             82
Charlie         71
01_calculator_funcs.py— Calculator refactored into functions
CODE
def add(a, b): return a + b
def sub(a, b): return a - b
def mul(a, b): return a * b
def div(a, b): return a / b if b else "Error: division by zero"

a = float(input("a: "))
b = float(input("b: "))
print(f"  +: {add(a,b)}")
print(f"  -: {sub(a,b)}")
print(f"  *: {mul(a,b)}")
print(f"  /: {div(a,b)}")
02_stats.py— Statistical functions
CODE
def mean(lst):
    return sum(lst) / len(lst)

def variance(lst):
    m = mean(lst)
    return sum((x - m)**2 for x in lst) / len(lst)

def std_dev(lst):
    return variance(lst) ** 0.5

data = [10, 20, 30, 40, 50]
print(f"Mean:    {mean(data):.2f}")
print(f"Std Dev: {std_dev(data):.2f}")
▶ Output
Mean:    30.00
Std Dev: 14.14
03_recursive_factorial.py— Factorial using recursion
CODE
def factorial(n):
    """Return n! recursively."""
    if n <= 1:
        return 1
    return n * factorial(n - 1)

for i in range(1, 8):
    print(f"{i}! = {factorial(i)}")
▶ Output
1! = 1
2! = 2
3! = 6
4! = 24
5! = 120
6! = 720
7! = 5040
todo.py— Complete to-do app implementation
CODE
import json, os

FILE = "tasks.json"

def load_tasks():
    if os.path.exists(FILE):
        with open(FILE) as f:
            return json.load(f)
    return []

def save_tasks(tasks):
    with open(FILE, "w") as f:
        json.dump(tasks, f, indent=2)

def add_task(tasks, title):
    task_id = max((t["id"] for t in tasks), default=0) + 1
    tasks.append({"id": task_id, "title": title, "done": False})
    print(f"  [{task_id}] added.")

def list_tasks(tasks):
    if not tasks:
        print("  No tasks.")
        return
    print(f"  {'ID':<4} {'Status':<8} Title")
    for t in tasks:
        status = "[x]" if t["done"] else "[ ]"
        print(f"  {t['id']:<4} {status:<8} {t['title']}")
    done = sum(1 for t in tasks if t["done"])
    print(f"  Done: {done}/{len(tasks)}")

def mark_done(tasks, task_id):
    for t in tasks:
        if t["id"] == task_id:
            t["done"] = True
            print(f"  [{task_id}] marked as done.")
            return
    print(f"  Task {task_id} not found.")

def delete_task(tasks, task_id):
    orig = len(tasks)
    tasks[:] = [t for t in tasks if t["id"] != task_id]
    if len(tasks) < orig:
        print(f"  [{task_id}] deleted.")
    else:
        print(f"  Task {task_id} not found.")

def main():
    tasks = load_tasks()
    print("Todo App — type 'help' for commands")
    while True:
        line = input("> ").strip()
        if not line:
            continue
        parts = line.split(maxsplit=1)
        cmd = parts[0].lower()
        arg = parts[1] if len(parts) > 1 else ""
        if cmd == "add":
            if arg:
                add_task(tasks, arg)
                save_tasks(tasks)
            else:
                print("  Usage: add <title>")
        elif cmd == "list":
            list_tasks(tasks)
        elif cmd == "done":
            try:
                mark_done(tasks, int(arg))
                save_tasks(tasks)
            except ValueError:
                print("  Usage: done <id>")
        elif cmd == "delete":
            try:
                delete_task(tasks, int(arg))
                save_tasks(tasks)
            except ValueError:
                print("  Usage: delete <id>")
        elif cmd in ("quit", "exit"):
            print("  Bye!")
            break
        elif cmd == "help":
            print("  Commands: add <title>, list, done <id>, delete <id>, quit")
        else:
            print(f"  Unknown command: {cmd}")

if __name__ == "__main__":
    main()

📝 Exercises

Try them yourself first, then open the solution to compare.

Exercise 1

Student Grade Book

Goal: Store student names and scores in a dict; print average, highest, and lowest.

Requirements
  • Read N students from input
  • Store in dict {name: score}
  • Print average (2 decimal), top scorer, lowest scorer
▶Toggle solution
SOLUTION
n = int(input("Students: "))
grades = {}
for _ in range(n):
    name = input("  Name: ")
    score = int(input("  Score: "))
    grades[name] = score
avg = sum(grades.values()) / len(grades)
top = max(grades, key=grades.get)
low = min(grades, key=grades.get)
print(f"Average: {avg:.2f}")
print(f"Top: {top} ({grades[top]})")
print(f"Lowest: {low} ({grades[low]})")
Exercise 2

Duplicate Detector

Goal: Find duplicate numbers in a list using a set.

Requirements
  • Read space-separated integers
  • Use a set to track seen numbers
  • Print duplicates in sorted order
Sample I/O
Numbers: 3 5 2 3 7 5 9
Duplicates: [3, 5]
▶Toggle solution
SOLUTION
nums = list(map(int, input('Numbers: ').split()))
seen, dups = set(), set()
for n in nums:
    if n in seen:
        dups.add(n)
    seen.add(n)
print('Duplicates:', sorted(dups))
Exercise 3

Password Validator

Goal: Check if a password meets complexity requirements.

Requirements
  • Minimum 8 characters
  • At least one digit (any char.isdigit())
  • At least one uppercase letter
  • Print each failed rule
Sample I/O
Password: hello
Failed: too short
Failed: no digit
Failed: no uppercase
▶Toggle solution
SOLUTION
pw = input("Password: ")
if len(pw) < 8:
    print("Failed: too short")
if not any(c.isdigit() for c in pw):
    print("Failed: no digit")
if not any(c.isupper() for c in pw):
    print("Failed: no uppercase")
if len(pw) >= 8 and any(c.isdigit() for c in pw) and any(c.isupper() for c in pw):
    print("Password OK")
Exercise 4

Word Reverser

Goal: Reverse each word in a sentence while keeping word order.

Requirements
  • Read a sentence from input
  • Reverse each word individually
  • Join with spaces and print
Sample I/O
Input: Hello World Python
Output: olleH dlroW nohtyP
▶Toggle solution
SOLUTION
sentence = input('Input: ')
result = ' '.join(w[::-1] for w in sentence.split())
print('Output:', result)
Exercise 5

Is Prime?

Goal: Write is_prime(n) that returns True if n is prime.

Requirements
  • Handle n < 2 → False
  • Check divisors only up to sqrt(n)
  • Test for n = 1, 2, 17, 100
▶Toggle solution
SOLUTION
def is_prime(n):
    if n < 2: return False
    for i in range(2, int(n**0.5)+1):
        if n % i == 0: return False
    return True

for n in [1, 2, 17, 100]:
    print(f'is_prime({n}) = {is_prime(n)}')
▶ Output
is_prime(1) = False
is_prime(2) = True
is_prime(17) = True
is_prime(100) = False
Exercise 6

Caesar Cipher

Goal: Write encrypt(text, shift) that shifts each letter by shift positions.

Requirements
  • Preserve case (upper/lower)
  • Non-alpha characters pass through unchanged
  • Write a matching decrypt(text, shift)
Sample I/O
encrypt('Hello, World!', 3) → 'Khoor, Zruog!'
▶Toggle solution
SOLUTION
def encrypt(text, shift):
    result = []
    for c in text:
        if c.isalpha():
            base = ord('A') if c.isupper() else ord('a')
            result.append(chr((ord(c) - base + shift) % 26 + base))
        else:
            result.append(c)
    return ''.join(result)

def decrypt(text, shift):
    return encrypt(text, -shift)

print(encrypt('Hello, World!', 3))
print(decrypt('Khoor, Zruog!', 3))
▶ Output
Khoor, Zruog!
Hello, World!
Exercise 7

Implement the base app

Goal: Implement the to-do app as described with add, list, done, delete, and quit.

Requirements
  • All 5 commands work correctly
  • Tasks persist across runs (JSON file)
  • Invalid input shows helpful error messages
Grading
  • · add/list work — 30%
  • · done/delete work — 30%
  • · JSON persistence — 30%
  • · Error handling — 10%
Exercise 8

Add priority support

Goal: Extend the app with a priority field (high/medium/low).

Requirements
  • add command accepts optional priority: add <title> [--priority high]
  • list sorts by priority: high → medium → low
  • Priority shown in list output
Example code / lecture materials

All lecture materials and example code are openly available on GitHub.

View on GitHub ↗

Comments 0

No comments yet. Be the first.

Only members can comment.

Comments with ads, abuse, personal information or illegal content are hidden or removed. Comments are shown with your nickname. Privacy Policy