[YOUR FUNCTION DISASTER PLACEHOLDER]
Describe a time when you copied a function, modified it slightly, and everything broke. What was the function supposed to do? Why did your changes break it?
I had been "writing" functions for years. Here's what I actually did:
- Search "Python function to [whatever]"
- Copy the first result
- Change variable names to match mine
- Pray it worked
- When it didn't, copy a different one
Then someone asked me to explain this function I had "written":
def process_temperature_data(readings, window=10, threshold=None):
"""Process temperature readings with moving average."""
if threshold is None:
threshold = []
# I had no idea why this was here
if not hasattr(process_temperature_data, 'history'):
process_temperature_data.history = []
# Or what this actually did
process_temperature_data.history.extend(readings)
# Or why this mattered
result = [sum(readings[i:i+window])/window
for i in range(len(readings)-window+1)]
# I just knew it "worked" sometimes
return result if result else readings
What I Didn't Understand
1. Functions Are Not Just Named Code Blocks
# What I thought functions were:
def calculate_stuff():
# Some code here
x = 10
y = 20
print(x + y)
# What I missed: Functions create a new scope!
x = 100
calculate_stuff() # Prints 30, not 120
print(x) # Still 100, function didn't change global x
2. The Return vs Print Confusion
# My constant mistake:
def get_average(numbers):
avg = sum(numbers) / len(numbers)
print(avg) # WRONG! This just displays
result = get_average([1, 2, 3])
print(result) # None! The function returned nothing
# What I should have written:
def get_average(numbers):
avg = sum(numbers) / len(numbers)
return avg # Actually gives back the value
result = get_average([1, 2, 3]) # Now result = 2.0
3. The Mutable Default Argument Trap
# The bug that haunted production for weeks:
def log_reading(value, history=[]): # DANGER!
history.append(value)
return history
# First sensor
sensor1_log = log_reading(100) # [100]
sensor1_log = log_reading(102) # [100, 102] - Expected!
# Second sensor - SURPRISE!
sensor2_log = log_reading(200) # [100, 102, 200] - WHAT?!
# Both sensors share the SAME list!
Functions in Industrial Systems
Pure Functions vs Side Effects
# PURE FUNCTION - Predictable, testable
def celsius_to_fahrenheit(celsius):
"""Always returns same output for same input."""
return (celsius * 9/5) + 32
# SIDE EFFECTS - Harder to test, can cause bugs
sensor_state = {'alerts': [], 'readings': []}
def check_temperature(temp):
"""Modifies external state - side effect!"""
if temp > 1500:
sensor_state['alerts'].append(f"High temp: {temp}") # Side effect
send_email_alert() # Another side effect
sensor_state['readings'].append(temp) # And another
return temp > 1500
Function Composition
# Small, focused functions
def read_sensor(sensor_id):
"""Read single sensor value."""
return sensor_readings[sensor_id]
def validate_reading(value, min_val=0, max_val=2000):
"""Check if reading is valid."""
return min_val <= value <= max_val
def convert_to_celsius(fahrenheit):
"""Convert F to C."""
return (fahrenheit - 32) * 5/9
def process_sensor(sensor_id):
"""Compose smaller functions."""
raw_value = read_sensor(sensor_id)
if validate_reading(raw_value):
return convert_to_celsius(raw_value)
return None
Exercise: Function Mastery
Build a Temperature Alert System
Create functions that properly handle industrial sensor data:
The Hidden Truth No One Talks About
I copy-pasted functions for 3 years before understanding scope, return values, or side effects.
How The Giants Use (and Abuse) This
Tech Giants' Reality:
• Ariane 5 rocket - function overflow, $370M explosion after 37 seconds
• Therac-25 radiation machine - function race condition killed 6 patients
• Intel Pentium FDIV bug - floating point function error, $475M recall
• Ariane 5 rocket - function overflow, $370M explosion after 37 seconds
• Therac-25 radiation machine - function race condition killed 6 patients
• Intel Pentium FDIV bug - floating point function error, $475M recall
The Disaster That Made Headlines
Citibank's $900M accident - function meant to pay $8M paid $900M instead
💰 The Real Cost:
$460M - Knight Capital again, wrong function version deployed
$460M - Knight Capital again, wrong function version deployed
The Code That Actually Matters
# Real implementation goes here
The Revelation:
Functions are contracts - break the contract, break production
Functions are contracts - break the contract, break production
# Fix these broken functions:
def calculate_average(readings, last_n):
"""Calculate average of last n readings."""
# BUG: What if readings has fewer than last_n elements?
return sum(readings[-last_n:]) / last_n
def add_alert(message, alerts=[]):
"""Add alert to list."""
# BUG: Mutable default argument!
alerts.append(message)
return alerts
def check_sensor_health(readings):
"""Check if sensor is working properly."""
avg = sum(readings) / len(readings)
print(f"Average: {avg}")
# BUG: No return statement!
def process_batch(sensor_data):
"""Process batch of sensor data."""
for reading in sensor_data:
if reading > 1500:
alert = True
else:
alert = False
return alert # BUG: Only returns last value!
# Your challenge: Fix all bugs and create a working system
The Truth About Functions
Function Mastery Checklist:
✓ I can explain what parameters vs arguments are
✓ I understand scope and namespace
✓ I know when to use return vs print
✓ I can identify and fix side effects
✓ I understand *args and **kwargs
✓ I can write pure functions
✓ I know why mutable defaults are dangerous
✓ I can explain what parameters vs arguments are
✓ I understand scope and namespace
✓ I know when to use return vs print
✓ I can identify and fix side effects
✓ I understand *args and **kwargs
✓ I can write pure functions
✓ I know why mutable defaults are dangerous
[YOUR FUNCTION ENLIGHTENMENT PLACEHOLDER]
When did functions finally click for you? What concept made the difference?