πŸ”€ Prerequisite β€’ Programming

Control Flow in Python

Control flow lets your code make decisions and repeat actions. These concepts power everything from training loops that iterate millions of times to conditionals that check model performanceβ€”essential patterns in every AI codebase.

⏱ Estimated reading time: 20-25 minutes

🎯 What You'll Learn

  • How to use if/elif/else for decision making
  • For loops to iterate over sequences
  • While loops for condition-based repetition
  • Loop control: break, continue, and else clauses
  • Common patterns used in AI code

1 Conditionals (if/elif/else)

Conditionals let your program make decisions based on conditions. The basic structure is if, optionally followed by elif (else if) and else.

Python
accuracy = 0.92

if accuracy >= 0.95:
    print("Excellent model!")
elif accuracy >= 0.90:
    print("Good model")
elif accuracy >= 0.80:
    print("Decent model")
else:
    print("Needs improvement")

# Output: Good model

⚠️ Indentation Matters!

Python uses indentation (4 spaces) to define code blocks. Unlike other languages that use braces {}, Python requires consistent indentation. Mixing tabs and spaces causes errors!

Comparison and Logical Operators

Python
epoch = 50
loss = 0.05
patience = 10
epochs_without_improvement = 12

# Combining conditions with 'and', 'or', 'not'
if loss < 0.1 and epoch > 10:
    print("Training converging well")

if loss > 1.0 or epochs_without_improvement > patience:
    print("Consider stopping training")

if not (loss < 0.01):
    print("Loss hasn't reached target yet")

Checking Types and Values

Python
model = None
data = []

# Check for None
if model is None:
    print("Model not loaded")

# Check for empty (falsy values)
if not data:
    print("No data available")

# Check if value in collection
supported_models = ["gpt-4", "claude", "llama"]
if "gpt-4" in supported_models:
    print("GPT-4 is supported")

πŸ€– Conditionals in AI Code

Conditionals are everywhere: checking if GPU is available, early stopping when validation loss stops improving, switching between training and evaluation mode, handling different input formats, and implementing learning rate schedules.

2 For Loops

For loops iterate over sequences (lists, strings, ranges, etc.). They're the most common loop type in AI codeβ€”used for training epochs, processing batches, and more.

Python
# Iterating over a list
models = ["BERT", "GPT", "T5"]
for model in models:
    print(f"Testing {model}")

# Using range() for counting
for epoch in range(5):  # 0, 1, 2, 3, 4
    print(f"Epoch {epoch}")

# range(start, stop, step)
for i in range(0, 100, 10):  # 0, 10, 20, ..., 90
    print(i)

ℹ️ Important: Python Starts at 0

This is a very common beginner confusion!

range() starts at 0 and stops before the end:
β€’ range(5) gives 0, 1, 2, 3, 4 β€” starts at 0, stops before 5
β€’ range(1, 5) gives 1, 2, 3, 4 β€” starts at 1, stops before 5

Lists are also 0-indexed:
β€’ my_list[0] is the first item
β€’ my_list[1] is the second item
β€’ A list with 5 items has indices: 0, 1, 2, 3, 4

Why? This design ensures range(len(items)) always gives valid indices!

Enumerate: Index + Value

Python
layers = ["embedding", "transformer", "output"]

# Get both index and value
for i, layer in enumerate(layers):
    print(f"Layer {i}: {layer}")

# Output:
# Layer 0: embedding
# Layer 1: transformer
# Layer 2: output

# Start counting from 1
for i, layer in enumerate(layers, start=1):
    print(f"Layer {i}: {layer}")

Zip: Iterate Multiple Sequences

Python
predictions = [0.9, 0.3, 0.7]
labels = [1, 0, 1]

# Iterate through pairs
for pred, label in zip(predictions, labels):
    correct = (pred > 0.5) == label
    print(f"Pred: {pred:.1f}, Label: {label}, Correct: {correct}")

# Output:
# Pred: 0.9, Label: 1, Correct: True
# Pred: 0.3, Label: 0, Correct: True
# Pred: 0.7, Label: 1, Correct: True

πŸ€– The Training Loop Pattern

Every neural network training uses nested for loops: outer loop for epochs, inner loop for batches. This pattern is universal across frameworks.

Typical Training Loop
# Pseudocode for a typical training loop
num_epochs = 10
batches = [[1,2], [3,4], [5,6]]  # Example data batches

for epoch in range(num_epochs):
    total_loss = 0
    
    for batch_idx, batch in enumerate(batches):
        # Forward pass, compute loss, backward pass
        loss = 0.5  # placeholder
        total_loss += loss
    
    avg_loss = total_loss / len(batches)
    print(f"Epoch {epoch+1}/{num_epochs}, Loss: {avg_loss:.4f}")

3 While Loops

While loops repeat as long as a condition is true. They're useful when you don't know in advance how many iterations you need.

Python
# Basic while loop
loss = 1.0
threshold = 0.1
iteration = 0

while loss > threshold:
    loss *= 0.9  # Simulate loss decreasing
    iteration += 1
    print(f"Iteration {iteration}: loss = {loss:.4f}")

print(f"Converged after {iteration} iterations")

⚠️ Avoid Infinite Loops

Make sure your while condition will eventually become False! Always have a way to exit the loop (condition change or max iterations).

Safe While Loop
# Always include a maximum iteration limit
loss = 1.0
max_iterations = 1000
iteration = 0

while loss > 0.01 and iteration < max_iterations:
    loss *= 0.99
    iteration += 1

if iteration == max_iterations:
    print("Warning: Max iterations reached")
else:
    print(f"Converged in {iteration} iterations")

4 Loop Control

break: Exit the Loop Early

Python
# Early stopping when validation loss stops improving
losses = [0.5, 0.4, 0.35, 0.36, 0.37, 0.38]  # Simulated losses
patience = 2
no_improvement = 0
best_loss = float('inf')

for epoch, loss in enumerate(losses):
    if loss < best_loss:
        best_loss = loss
        no_improvement = 0
        print(f"Epoch {epoch}: New best loss {loss}")
    else:
        no_improvement += 1
        print(f"Epoch {epoch}: No improvement ({no_improvement}/{patience})")
    
    if no_improvement >= patience:
        print("Early stopping!")
        break

continue: Skip to Next Iteration

Python
# Skip invalid data points
data_points = [0.5, None, 0.8, -0.1, 0.9, None]

for i, value in enumerate(data_points):
    if value is None:
        print(f"Skipping None at index {i}")
        continue
    
    if value < 0:
        print(f"Skipping negative value at index {i}")
        continue
    
    print(f"Processing: {value}")

else Clause on Loops

Python has a unique feature: an else clause on loops that runs only if the loop completes normally (not via break).

Python
# Check if any loss exceeds threshold
losses = [0.1, 0.2, 0.15, 0.08]
threshold = 0.5

for loss in losses:
    if loss > threshold:
        print(f"Found loss above threshold: {loss}")
        break
else:
    # This runs only if we didn't break
    print("All losses are below threshold!")

5 List Comprehensions

List comprehensions are a concise way to create lists. They're faster and more "Pythonic" than equivalent for loops.

Python
# Traditional for loop
squares = []
for x in range(5):
    squares.append(x ** 2)
# [0, 1, 4, 9, 16]

# List comprehension (same result, one line)
squares = [x ** 2 for x in range(5)]
# [0, 1, 4, 9, 16]
    Anatomy of a List Comprehension:
    
    [ expression   for  item  in  sequence ]
      ──────────   ───  ────  ──  ────────
           β”‚        β”‚    β”‚         β”‚
           β”‚        β”‚    β”‚         └─ What to iterate over
           β”‚        β”‚    β”‚
           β”‚        β”‚    └─────────── Variable name for each element
           β”‚        β”‚
           β”‚        └──────────────── Keyword "for"
           β”‚
           └───────────────────────── What to compute for each item
    
    Example: [x**2  for  x  in  range(5)]
              ↓              ↓
         "square x"    "for x = 0,1,2,3,4"
                    

Read it like English: "give me x squared, for each x in range(5)"

With Conditions

Python
# Filter: only keep items matching condition
numbers = [1, -2, 3, -4, 5]
positive = [x for x in numbers if x > 0]
# [1, 3, 5]

# Transform + filter
doubled_positive = [x * 2 for x in numbers if x > 0]
# [2, 6, 10]

# Conditional expression (ternary)
abs_values = [x if x >= 0 else -x for x in numbers]
# [1, 2, 3, 4, 5]

πŸ€– Comprehensions in AI

Comprehensions are used constantly: [f.read() for f in files] to load data, [pred > 0.5 for pred in predictions] for thresholding, [layer for layer in model.layers if 'attention' in layer.name] to filter layers.

Dictionary and Set Comprehensions

Python
# Dictionary comprehension
models = ["bert", "gpt", "t5"]
accuracies = [0.92, 0.95, 0.89]

results = {model: acc for model, acc in zip(models, accuracies)}
# {'bert': 0.92, 'gpt': 0.95, 't5': 0.89}

# Set comprehension (unique values)
labels = [1, 0, 1, 2, 0, 2, 1]
unique_labels = {label for label in labels}
# {0, 1, 2}

6 Practice Exercises

✏️ Exercise 1: Conditional Logic

Write code that checks if a model is ready for deployment: accuracy must be β‰₯ 0.90 AND loss must be ≀ 0.2. Test with accuracy=0.92, loss=0.15.
Click to reveal solution β–Ό
accuracy = 0.92
loss = 0.15

if accuracy >= 0.90 and loss <= 0.2:
    print("Model ready for deployment!")
else:
    print("Model needs more training")
# Output: Model ready for deployment!

✏️ Exercise 2: Training Loop

Simulate a training loop for 5 epochs. Each epoch, loss starts at 1.0 and decreases by 10%. Print epoch number and loss for each.
Click to reveal solution β–Ό
loss = 1.0

for epoch in range(1, 6):
    loss *= 0.9  # Decrease by 10%
    print(f"Epoch {epoch}/5 - Loss: {loss:.4f}")

# Output:
# Epoch 1/5 - Loss: 0.9000
# Epoch 2/5 - Loss: 0.8100
# ...

✏️ Exercise 3: List Comprehension

Given predictions = [0.2, 0.7, 0.4, 0.9, 0.1], create a list of binary predictions where values β‰₯ 0.5 become 1 and values < 0.5 become 0.
Click to reveal solution β–Ό
predictions = [0.2, 0.7, 0.4, 0.9, 0.1]

# Using list comprehension with conditional
binary = [1 if p >= 0.5 else 0 for p in predictions]
print(binary)  # [0, 1, 0, 1, 0]

🎯 Key Takeaways

  • if/elif/else for decision makingβ€”indentation defines code blocks
  • for loops iterate over sequences; use range() for counting
  • enumerate() gives you index + value; zip() for parallel iteration
  • while loops repeat while condition is trueβ€”always include exit condition
  • break exits loop; continue skips to next iteration
  • List comprehensions are concise: [x**2 for x in range(5) if x > 0]

Next Steps

Now you can control program flow! Next, learn about functions and data structuresβ€”the building blocks for organizing larger programs.