Welcome to Week 6

Today’s Agenda:

  • Control statements for business logic
  • Iteration for automation
  • Functions for reusable code
  • Mid-term project discussion & timeline

Today’s Format: Working Lecture

This is a hands-on session - you’ll be coding!

Our approach:

  1. 📖 Concept - Why this matters in business analytics
  2. 💡 Illustration - I’ll demonstrate with an example
  3. 💻 Challenge - You implement it in Google Colab
  4. Solution - We review together

Action item:

Open the Week 6 companion notebook in Google Colab and follow along as we work through today’s examples.

Control Statements for Business Logic

Concept: Making Decisions in Code

Business logic requires conditional decisions:

  • If customer is VIP → premium discount
  • If inventory is low → reorder alert
  • If sales exceed target → pay bonus

Control statements automate business rules.



Think About It

What examples of conditional logic have you encountered in your daily interactions with organizations? (shopping, banking, subscriptions, etc.)

Illustration 1: Simple if Statement

Scenario: Alert when inventory is low

# Low inventory
stock_level = 5

if stock_level < 10:
    print("🚨 URGENT: Reorder needed!")

print(f"Current stock: {stock_level} units")
🚨 URGENT: Reorder needed!
Current stock: 5 units
# Sufficient inventory
stock_level = 15

if stock_level < 10:
    print("🚨 URGENT: Reorder needed!")

print(f"Current stock: {stock_level} units")
Current stock: 15 units



Note

When to use: You only need to take action if a condition is True.

Illustration 2: if/else Statement

Scenario: Two possible outcomes based on a condition

# VIP customer
base_price = 100
is_vip = True

if is_vip:
    final_price = base_price * 0.8
    print(f"VIP discount applied!")
else:
    final_price = base_price * 0.95
    print(f"Standard price")

print(f"Price: ${final_price}")
VIP discount applied!
Price: $80.0
# Regular customer
base_price = 100
is_vip = False

if is_vip:
    final_price = base_price * 0.8
    print(f"VIP discount applied!")
else:
    final_price = base_price * 0.95
    print(f"Standard price")

print(f"Price: ${final_price}")
Standard price
Price: $95.0



Note

When to use: You have exactly two paths - do one thing OR another.

Illustration 3: Multi-Branch if/elif/else

Scenario: Multiple conditions to check in order

# High-value customer
annual_spend = 12500

if annual_spend >= 10000:
    segment = "High Value"
    strategy = "Personal account manager"
elif annual_spend >= 5000:
    segment = "Medium Value"
    strategy = "Quarterly check-ins"
elif annual_spend >= 1000:
    segment = "Low Value"
    strategy = "Email campaigns"
else:
    segment = "Inactive"
    strategy = "Re-engagement campaign"

print(f"{segment}{strategy}")
High Value → Personal account manager
# Medium-value customer
annual_spend = 7500

if annual_spend >= 10000:
    segment = "High Value"
    strategy = "Personal account manager"
elif annual_spend >= 5000:
    segment = "Medium Value"
    strategy = "Quarterly check-ins"
elif annual_spend >= 1000:
    segment = "Low Value"
    strategy = "Email campaigns"
else:
    segment = "Inactive"
    strategy = "Re-engagement campaign"

print(f"{segment}{strategy}")
Medium Value → Quarterly check-ins

Note

When to use: You have multiple conditions to check in a specific order.

Caution: Order Matters!

Common Mistake

The order of conditions in if/elif/else statements matters! Python checks conditions top to bottom and stops at the first True condition.

✅ Correct Order (Most to Least Specific)

# Check from high to low
annual_spend = 12500

if annual_spend >= 10000:
    segment = "High Value"
elif annual_spend >= 5000:
    segment = "Medium Value"
elif annual_spend >= 1000:
    segment = "Low Value"
else:
    segment = "Inactive"

print(f"Segment: {segment}")
Segment: High Value

❌ Wrong Order (Least to Most Specific)

# Check from low to high - WRONG!
annual_spend = 12500

if annual_spend >= 1000:
    segment = "Low Value"  # Oops! Stops here
elif annual_spend >= 5000:
    segment = "Medium Value"  # Never reached
elif annual_spend >= 10000:
    segment = "High Value"  # Never reached
else:
    segment = "Inactive"

print(f"Segment: {segment}")
Segment: Low Value

Challenge: VIP Discount Logic

Business Rules:

  • VIP customers: 20% discount
  • Premium customers: 15% discount
  • Regular customers: 5% discount

Pseudocode to guide you:

customer_type = ???

if _________ is '___':
    set discount to 0.20
elif _________ is '___':
    set discount to 0.15
else:
    set discount to 0.05


Your Task: Write code that assigns the correct discount based on customer_type.

Test with:

  • customer_type = 'VIP' (should get 0.20)
  • customer_type = 'Premium' (should get 0.15)
  • customer_type = 'Regular' (should get 0.05)

Solution: VIP Discount Logic

# Solution
customer_type = 'VIP'

if customer_type == 'VIP':
    discount = 0.20
elif customer_type == 'Premium':
    discount = 0.15
else:
    discount = 0.05

print(f"{customer_type} customer receives {discount:.0%} discount")
VIP customer receives 20% discount

Challenge: Grocery Loyalty Classifier

Your turn — write this one from scratch.

Business rules:

Monthly Spend Loyalty Status Discount
≥ $500 Gold 10%
≥ $200 Silver 5%
≥ $50 Bronze 2%
< $50 No Status 0%

Write code that:

  1. Sets a monthly_spend variable
  2. Assigns loyalty_status and discount using if/elif/else
  3. Prints: f"${monthly_spend}/month → {loyalty_status} ({discount:.0%} off)"

Test with: $650 → Gold, $275 → Silver, $75 → Bronze, $30 → No Status

Solution: Grocery Loyalty Classifier

monthly_spend = 650

if monthly_spend >= 500:
    loyalty_status = "Gold"
    discount = 0.10
elif monthly_spend >= 200:
    loyalty_status = "Silver"
    discount = 0.05
elif monthly_spend >= 50:
    loyalty_status = "Bronze"
    discount = 0.02
else:
    loyalty_status = "No Status"
    discount = 0.0

print(f"${monthly_spend}/month → {loyalty_status} ({discount:.0%} off)")
$650/month → Gold (10% off)

Concept: Conditional Logic on DataFrames

Apply conditional logic to entire columns at once:

  • Use np.where() for if/else logic on pandas columns
  • Use np.select() for multi-branch if/elif/else logic
  • Processes thousands of rows in one operation

Illustration: np.where() for if/else

import pandas as pd
import numpy as np

# Customer data
customers = pd.DataFrame({
    'customer_id': [1, 2, 3, 4, 5],
    'is_vip': [True, False, True, False, True],
    'base_price': [100, 100, 100, 100, 100]
})

# Apply VIP discount: if/else for entire column
customers['final_price'] = np.where(
    customers['is_vip'],              # Condition
    customers['base_price'] * 0.8,    # If True
    customers['base_price']           # If False
)

customers
customer_id is_vip base_price final_price
0 1 True 100 80.0
1 2 False 100 100.0
2 3 True 100 80.0
3 4 False 100 100.0
4 5 True 100 80.0

Challenge: Flag Transactions with np.where()

Scenario: Use the Complete Journey transactions data to classify purchases.

from completejourney_py import get_data
import numpy as np

df = get_data()['transactions']

Your task: Use np.where() to add two new columns:

  1. 'value_tier''premium' if sales_value > 10, else 'standard'
  2. 'disc_flag''discounted' if retail_disc > 0, else 'full price'

Then use .value_counts() on each to see the split.

Solution: Flag Transactions with np.where()

from completejourney_py import get_data
import numpy as np

df = get_data()['transactions']

df['value_tier'] = np.where(df['sales_value'] > 10, 'premium', 'standard')
df['value_tier'].value_counts()
value_tier
standard    1424042
premium       45265
Name: count, dtype: int64
df['disc_flag'] = np.where(df['retail_disc'] > 0, 'discounted', 'full price')
df['disc_flag'].value_counts()
disc_flag
discounted    736369
full price    732938
Name: count, dtype: int64

Iteration for Business Automation

Concept: Automating Repetitive Tasks

Business analytics involves repetitive operations:

  • Calculate metrics across multiple stores
  • Process files for each month
  • Apply transformations to product categories

Note

for loops automate what would otherwise be manual copy-paste.

Illustration 1: Simple List Iteration

Scenario: Calculate 10% commission on each sale

# Sales amounts from five transactions
sales_amounts = [45000, 52000, 38000, 41000, 67000]

# Calculate commission for each
for sales in sales_amounts:
    commission = sales * 0.10
    print(f"Sales: ${sales:,} → Commission: ${commission:,.0f}")
Sales: $45,000 → Commission: $4,500
Sales: $52,000 → Commission: $5,200
Sales: $38,000 → Commission: $3,800
Sales: $41,000 → Commission: $4,100
Sales: $67,000 → Commission: $6,700

Pattern: Iterate through each item, perform calculation, use result

Sometimes we iterate and just store the results:

commissions = []

for sales in sales_amounts:
    commission = sales * 0.10
    commissions.append(commission)

print(commissions)    
[4500.0, 5200.0, 3800.0, 4100.0, 6700.0]

Illustration 2: Dictionary Iteration

Scenario: Extract store names and sales from dictionary

# Store performance data
store_data = {
    'Downtown': 125000,
    'Mall': 98000,
    'Suburbs': 142000,
    'Airport': 87000
}

# Iterate through key-value pairs
for store_name, sales in store_data.items():
    commission = sales * 0.10
    print(f"{store_name:8}: {commission}")
Downtown: 12500.0
Mall    : 9800.0
Suburbs : 14200.0
Airport : 8700.0

Pattern: Use .items() to get both keys and values from dictionary

Illustration 3: List Comprehensions

Scenario: Apply discount to all prices in one line

Traditional for loop:

# Original prices
prices = [29.99, 49.99, 19.99, 89.99]

# Apply 15% discount
discounted = []
for price in prices:
    new_price = price * 0.85
    discounted.append(new_price)

print(discounted)
[25.4915, 42.4915, 16.9915, 76.49149999999999]

List comprehension:

# Original prices
prices = [29.99, 49.99, 19.99, 89.99]

# Apply 15% discount in one line
discounted = [price * 0.85 for price in prices]

print(discounted)
[25.4915, 42.4915, 16.9915, 76.49149999999999]


List comprehension is simply:

[expression for item in list]

Challenge: Loyalty Classifier — Now With a Loop

Earlier you classified one household’s loyalty status with if/elif/else.

Now use a for loop to classify all of them at once.

Data:

households = [650, 275, 75, 30, 520, 190]

Your task: Loop over households and for each spending amount, print:

"$X/month → Status (Y% off)"

using the same Gold / Silver / Bronze / No Status rules from before.

Solution: Loyalty Classifier — Now With a Loop

households = [650, 275, 75, 30, 520, 190]

for spend in households:
    if spend >= 500:
        status, disc = "Gold", 0.10
    elif spend >= 200:
        status, disc = "Silver", 0.05
    elif spend >= 50:
        status, disc = "Bronze", 0.02
    else:
        status, disc = "No Status", 0.0
    print(f"${spend}/month → {status} ({disc:.0%} off)")
$650/month → Gold (10% off)
$275/month → Silver (5% off)
$75/month → Bronze (2% off)
$30/month → No Status (0% off)
$520/month → Gold (10% off)
$190/month → Bronze (2% off)

Tip

The pattern: Put your if/elif/else logic inside the loop body — Python runs the full conditional for each item in the list.

Challenge: Temperature Converter

Scenario: You have 10 days of Celsius temperature readings and need to convert them to Fahrenheit.

Data:

celsius_temps = [20, 22, 19, 25, 23, 18, 21, 24, 20, 22]

Conversion Formula: fahrenheit = (celsius * 9/5) + 32

Your Task (Part 1): Use a for loop to:

  1. Convert each temperature to Fahrenheit
  2. Store results in a new list called fahrenheit_temps

Your Task (Part 2): Do the same conversion using a list comprehension

Answer this

Are these “goflable” temperatures?

Solution: Temperature Converter

Part 1: Using a for loop

# Given data
celsius_temps = [20, 22, 19, 25, 23, 18, 21, 24, 20, 22]

# Convert using for loop
fahrenheit_temps = []
for celsius in celsius_temps:
    fahrenheit = (celsius * 9/5) + 32
    fahrenheit_temps.append(fahrenheit)

print("For loop result:", fahrenheit_temps)
For loop result: [68.0, 71.6, 66.2, 77.0, 73.4, 64.4, 69.8, 75.2, 68.0, 71.6]

Part 2: Using list comprehension

# Convert using list comprehension
fahrenheit_temps = [(celsius * 9/5) + 32 for celsius in celsius_temps]

print("List comprehension result:", fahrenheit_temps)
List comprehension result: [68.0, 71.6, 66.2, 77.0, 73.4, 64.4, 69.8, 75.2, 68.0, 71.6]

Functions for Reusable Code

Concept: Don’t Repeat Yourself (DRY)

The danger of copy-paste code:

# Calculate profit margin for three products (copied and pasted)
# Profit margin = (revenue - cost) / revenue * 100

product_a_margin = (revenue_a - cost_a) / revenue_a * 100
product_b_margin = (revenue_b - cost_b) / revenue_a * 100
product_c_margin = (revenue_c - cost_c) / revenue_c * 100

Problems with repetition:

  • Easy to introduce typos when copying/pasting
  • If formula changes, must update in multiple places
  • Harder to spot errors across multiple lines

Tip

Functions package logic into reusable, testable units - write once, use many times.

Anatomy of a Good Function

Level 1: Basic function - inputs and output

def calculate_profit_margin(revenue, cost):
    margin = (revenue - cost) / revenue
    return margin

# Test it
calculate_profit_margin(1000, 600)
0.4

Anatomy of a Good Function

Level 2: Add documentation (docstring)

def calculate_profit_margin(revenue, cost):
    """
    Calculate profit margin as a percentage.

    Args:
        revenue: Total revenue from sales
        cost: Total cost of goods sold

    Returns:
        Profit margin as a percentage
    """
    margin = (revenue - cost) / revenue
    return margin

calculate_profit_margin(1000, 600)
0.4


Why docstrings?

Team members (including future you) can understand what the function does

Anatomy of a Good Function

Level 3: Add type hints (optional but helpful)

def calculate_profit_margin(revenue: float, cost: float) -> float:
    """
    Calculate profit margin as a percentage.

    Args:
        revenue: Total revenue from sales
        cost: Total cost of goods sold

    Returns:
        Profit margin as a percentage
    """
    margin = (revenue - cost) / revenue
    return margin

calculate_profit_margin(1000, 600)
0.4

Why type hints?

Makes it clear what types of data the function expects and returns

Anatomy of a Good Function

Level 4: Add input validation (defensive programming)

Tip

Why validate? Catch problems early with clear error messages instead of producing nonsensical results

Without validation:

def calculate_profit_margin(revenue: float, cost: float) -> float:
    """Calculate profit margin."""
    margin = (revenue - cost) / revenue * 100
    return margin

# Problematic inputs
result = calculate_profit_margin(1000, 1200)
print(f"Margin: {result:.1f}%")  # Negative!
Margin: -20.0%

With validation:

def calculate_profit_margin(revenue: float, cost: float) -> float:
    """Calculate profit margin with validation."""

    # Check inputs
    if revenue <= 0:
        raise ValueError("Revenue must be positive")
    if cost < 0:
        raise ValueError("Cost cannot be negative")
    if cost > revenue:
        raise ValueError("Cost exceeds revenue!")

    margin = (revenue - cost) / revenue * 100
    return margin

# Now catches the problem
calculate_profit_margin(1000, 1200)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[26], line 16
     12     margin = (revenue - cost) / revenue * 100
     13     return margin
     14 
     15 # Now catches the problem
---> 16 calculate_profit_margin(1000, 1200)

Cell In[26], line 10, in calculate_profit_margin(revenue, cost)
      6         raise ValueError("Revenue must be positive")
      7     if cost < 0:
      8         raise ValueError("Cost cannot be negative")
      9     if cost > revenue:
---> 10         raise ValueError("Cost exceeds revenue!")
     11 
     12     margin = (revenue - cost) / revenue * 100
     13     return margin

ValueError: Cost exceeds revenue!

Illustration: ROI Function

def calculate_roi(revenue, cost):
    """Calculate return on investment as a percentage."""
    return (revenue - cost) / cost * 100

# Use the function multiple times
roi_campaign_a = calculate_roi(15000, 10000)
roi_campaign_b = calculate_roi(8000, 5000)
roi_campaign_c = calculate_roi(12000, 9000)

print(f"Campaign A ROI: {roi_campaign_a:.1f}%")
print(f"Campaign B ROI: {roi_campaign_b:.1f}%")
print(f"Campaign C ROI: {roi_campaign_c:.1f}%")
Campaign A ROI: 50.0%
Campaign B ROI: 60.0%
Campaign C ROI: 33.3%

Or even more likely…

# Campaign performance data
campaigns = {
    'Email': {'revenue': 15000, 'cost': 10000},
    'Social': {'revenue': 8000, 'cost': 5000},
    'Search': {'revenue': 12000, 'cost': 9000},
    'Display': {'revenue': 6000, 'cost': 4500}
}

roi = {name: calculate_roi(data['revenue'], data['cost']) for name, data in campaigns.items()}
roi
{'Email': 50.0,
 'Social': 60.0,
 'Search': 33.33333333333333,
 'Display': 33.33333333333333}

Power move:

Functions + iteration = scalable, maintainable analysis

Challenge: Customer Lifetime Value

Business Formula:

CLV = (Average Order Value × Purchase Frequency × Gross Margin) × Customer Lifespan

Your Task: Write a function customer_lifetime_value() that:

  • Takes 4 parameters: avg_order_value, purchase_frequency, gross_margin, customer_lifespan
  • Returns the CLV

Test with:

  • customer_lifetime_value(150, 4, 0.25, 3)450.0
  • customer_lifetime_value(200, 6, 0.30, 5)1800.0
  • customer_lifetime_value(100, 3, 0.20, 2)120.0
  • customer_lifetime_value(75, 12, 0.15, 4)540.0

Solution: Customer Lifetime Value

# Solution
def customer_lifetime_value(avg_order_value, purchase_frequency, gross_margin, customer_lifespan):
    """Calculate Customer Lifetime Value (CLV)."""
    annual_value = avg_order_value * purchase_frequency * gross_margin
    clv = annual_value * customer_lifespan
    return round(clv, 2)

# Test the function
clv = customer_lifetime_value(
    avg_order_value=150,
    purchase_frequency=4,
    gross_margin=0.25,
    customer_lifespan=3
)
print(f"Customer Lifetime Value: ${clv}")
Customer Lifetime Value: $450.0
print(customer_lifetime_value(200, 6, 0.30, 5))
print(customer_lifetime_value(100, 3, 0.20, 2))
print(customer_lifetime_value(75, 12, 0.15, 4))
1800.0
120.0
540.0

Functions + DataFrames: Scaling Analysis

Scenario: Apply custom function to each row of a DataFrame

import pandas as pd

# Customer portfolio data
customers_df = pd.DataFrame({
    'customer_id': ['C001', 'C002', 'C003', 'C004'],
    'avg_order': [150, 200, 100, 75],
    'frequency': [4, 6, 3, 12],
    'margin': [0.25, 0.30, 0.20, 0.15],
    'lifespan': [3, 5, 2, 4]
})

# Apply our function to each row
customers_df['clv'] = customers_df.apply(
    lambda row: customer_lifetime_value(
        avg_order_value=row['avg_order'],
        purchase_frequency=row['frequency'],
        gross_margin=row['margin'],
        customer_lifespan=row['lifespan']
    ),
    axis=1
)

customers_df
customer_id avg_order frequency margin lifespan clv
0 C001 150 4 0.25 3 450.0
1 C002 200 6 0.30 5 1800.0
2 C003 100 3 0.20 2 120.0
3 C004 75 12 0.15 4 540.0

Note

This week’s readings (Chapters 16-18) will make you very comfortable with these kinds of DataFrame operations!

Key Principles: When to Use Functions

Create functions when you:

  • Repeat the same calculation 3+ times
  • Need consistent business metric calculations
  • Want to test logic independently
  • Share code with team members

Avoid over-engineering:

  • Don’t create functions for one-time operations
  • Keep functions focused on a single task
  • Document what the function does and why

Programming Concepts Recap

What we covered today:

  1. Control statements - Automate business decisions (if/elif/else)
  2. Iteration - Process multiple items efficiently (for loops)
  3. Functions - Package reusable logic (DRY principle)

These skills apply directly to your mid-term project!


Questions before we discuss the project?

Mid-term Project Discussion

Group Formation Check-In

Quick check: Let’s see where everyone stands

🙋‍♀️ Raise your hand if you are:

  • Already in a group and ready to go
  • Need to join a group today
  • Having trouble accessing Canvas groups

Important reminders:

  • Group size: 2-4 students
  • Must use pre-defined Canvas groups (People → Mid-Term Project)
  • DO NOT create your own group outside the Canvas list
  • Peer evaluations count toward 25% of engagement grade

If you need a group: We’ll solve this right now!

Rubric Walkthrough

Let’s review the grading criteria together

[Instructor will pull up Canvas rubric to walk through each component]

Key areas we’ll examine:

  • Business question clarity and focus
  • Analytical approach and methodology
  • Data preparation and joining requirements
  • Visualization quality and appropriateness
  • Written report formatting and narrative
  • Presentation delivery and business focus
  • Peer evaluation requirements

Questions to ask yourself: “What does ‘excellent’ look like for each component?”

Past Project Example Review

Let’s examine a strong example together

[Instructor will pull up one of the Canvas examples to review live]

What we’ll look for:

  • How they stated their business question clearly
  • Their analytical approach and logic flow
  • Quality of visualizations and insights
  • Actionable recommendations for the CEO
  • Professional presentation style

Key takeaway: Notice how they balance technical rigor with business communication

Technical Logistics & Questions

Submission Requirements:

  • File naming: YYYY_BANA7025_groupXX_finalproject.html
  • One person submits for the entire group
  • Submit together: HTML report AND presentation video
  • Plan ahead: Large files take time to upload

Recording your presentation:

  • Recommended: Zoom (start meeting, share screen, record)
  • Alternative: Kaltura in Canvas
  • Length: 3 minutes maximum
  • Audience: CEO/senior executives (no code!)

Questions about: Dataset access? Python packages? Technical issues?

Thursday Lab Planning

Most of you should have a signed-off business problem and a plan for the analyses needed to answer it. Use Thursday’s lab to execute that work — I’ll be circulating to provide feedback as you go.

If you don’t yet have sign-off or an analysis plan, that’s your first priority Thursday:

  • Get your business question approved by me or the TA
  • Map out the specific analyses needed to answer it (what data, what metric, what visualization?)

Once those are in place, start executing:

  • Work through your analyses in priority order
  • Ask for feedback early — don’t wait until something is finished
  • Aim to have at least one complete analysis by end of lab

Important

Come prepared: Laptop ready, proposal open, and a clear sense of what you’re working on Thursday.

Project Timeline: Final Push!

Week 5 (Done):

  • ✅ Groups formed
  • ✅ Business problem identified
  • ✅ Project proposal submitted

Week 6 — This Week:

  • ✅ Business question finalized & approved
  • 🔄 Analyses mapped out (Tuesday/Thursday)
  • 🔄 Begin executing analyses (Thursday lab)

Week 7 — Final Push:

  • 📊 Complete all analyses
  • 📝 Write report
  • 🎥 Record presentation
  • 📤 Submit by end of Week 7

Bottom line: Your foundation is set — Week 6 is about locking in the plan and getting work done.

Open floor for questions about:

  • Mid-term project: Requirements, expectations, logistics
  • Technical setup: Dataset access, Python environment, recording tools
  • Team coordination: Group work, meeting planning, task division
  • Today’s programming content: Control statements, iteration, functions
  • Thursday lab: What to bring, how to prepare

Summary and Next Steps

Key Takeaways

Today we covered:

  1. Control statements - Making business decisions in code
  2. Iteration - Automating repetitive business tasks
  3. Functions - Creating reusable, maintainable code
  4. Mid-term project - Timeline, requirements, and expectations

Next steps:

  • Thursday: Lab work mid-term project
  • Read: Chapters 16-18 in the textbook
  • Start thinking: What business questions interest you for the mid-term?

Remember: These programming concepts make you more efficient and your code more professional!