Day 4:Control Flow (`if/else`), Loops (`for`/`while`), Functions & Variable Scope
Battle-tested daily lesson note • 100% runnable code, interview Q&A, test suite & interactive quiz
Week 1 — Day 4: Control Flow (if/else), Loops (for/while), Functions & Variable Scope
Mentor's Note (10+ YOE Staff AI Engineer POV): Today you learn how to give your Python programs decision-making brains (
if/elif/else), repetition power (for/whileloops), and reusable building blocks (deffunctions).Why Senior AI Engineers care deeply about Day 4:
- Every AI Agent Loop (
while step < max_steps:) is just awhileloop with a circuit-breaker condition so a confused LLM doesn't burn $500 calling tools infinitely!- We cover the #1 most famous Python coding interview trap of all time: The Mutable Default Argument Bug (
def add_message(msg, history=[]):)—a bug that has caused catastrophic data leaks between different users' chat sessions in real AI startups!
Part 1: Control Flow (if / elif / else) & Python "Truthiness"
1.1 Basic Decision Making
confidence_score = 0.88
if confidence_score >= 0.85:
action = "RETURN_DIRECT_ANSWER"
elif confidence_score >= 0.50:
action = "ASK_CLARIFYING_QUESTION"
else:
action = "ESCALATE_TO_HUMAN_SRE"
1.2 "Truthiness" and "Falsiness" in Python
In Python, you don't need to write if len(messages) > 0: or if api_key != "":.
Every object in Python is automatically either Truthy or Falsy:
- Falsy values (evaluate to
Falsein anifcheck):False,None,0,0.0,""(empty string),[](empty list),{}(empty dict),set()(empty set).
- Truthy values: Everything else!
# Clean, Pythonic check:
if not retrieved_chunks:
print("No relevant documents found in vector database!")
Part 2: Loops (for and while), enumerate(), and zip()
2.1 for Loops with enumerate() and zip()
Beginners often write clunky for i in range(len(chunks)):. Professional Python engineers use enumerate() and zip():
chunks = ["## Redis Cache", "## Postgres Failover"]
scores = [0.94, 0.71]
# 1. enumerate() gives you BOTH the index number and the value!
for idx, chunk in enumerate(chunks, start=1):
print(f"Chunk #{idx}: {chunk}")
# 2. zip() pairs items from two lists together side-by-side!
for chunk, score in zip(chunks, scores):
print(f"{chunk} -> similarity={score}")
2.2 while Loops, break, and continue (The AI Agent Retry Loop!)
Whenever we call an LLM API or run an autonomous Agent, we use a while loop with a maximum retry/step cap (break):
attempt = 0
max_retries = 3
while attempt < max_retries:
attempt += 1
# If API call succeeds, exit the loop immediately with `break`:
if api_succeeded:
break
Part 3: Functions (def), *args, **kwargs & Variable Scope (LEGB)
3.1 Anatomy of a Clean Function
def calculate_chunk_overlap(
chunk_size: int, overlap_ratio: float = 0.10
) -> int:
"""Calculates how many tokens should overlap between adjacent RAG chunks."""
return int(chunk_size * overlap_ratio)
3.2 What Are *args and **kwargs? (Used Everywhere in PyTorch & FastAPI!)
*args(Positional Arguments Tuple): Collects any number of extra positional arguments into atuple.**kwargs(Keyword Arguments Dictionary): Collects any number of namedkey=valuearguments into adict(e.g., passingtemperature=0.0, top_p=0.9into an LLM wrapper!).
Part 4: THE #1 PYTHON INTERVIEW TRAP — Mutable Default Arguments!
[!CAUTION] Real-World AI Startup Disaster Story: A junior developer writes this function to append a user's message to a chat history list:
python# BUGGY CODE — NEVER DO THIS! def append_chat_message( user_msg: str, history: list[str] = [] ) -> list[str]: history.append(user_msg) return historyWhat goes wrong? In Python, default argument values (
history=[]) are evaluated ONLY ONCE when thedefstatement is first loaded into memory—NOT each time the function is called! That means User A callsappend_chat_message("My secret password is 123")returns["My secret password is 123"]. One second later, User B callsappend_chat_message("Hello")returns["My secret password is 123", "Hello"]! User A's private chat just leaked to User B because they shared the exact same[]list in memory!
The Safe, Professional Pattern (None Sentinel):
def append_chat_message(
user_msg: str, history: list[str] | None = None
) -> list[str]:
if history is None:
history = [] # Creates a brand-new list on EVERY call!
history.append(user_msg)
return history
Part 5: Hands-On Lab — Rule-Based SRE Incident Router & Safe Chat Session Manager (incident_router.py)
Check out src/incident_router.py (in Tab 2: Codes — click Run in Browser to execute) and run the script and tests:
python week01_computer_terminal_git_python_basics/day04_control_flow_loops_functions/src/incident_router.py
python -m unittest discover -s week01_computer_terminal_git_python_basics/day04_control_flow_loops_functions/tests -v