Emergency Fund
Each topic starts with a real scenario and a bar model, then three levels of exercises. Level 1 (Guided) fills in the blanks of a finished function. Level 2 (Practice) applies it to new numbers. Level 3 (Challenge) asks a new question with little scaffolding. The R and Python exercises run in your browser: click Run Code to try, Submit Answer to check, and use the hint or solution if you get stuck. Excel exercises have a solution you can reveal.
1 Book Topics
- What it is: cash set aside for the unexpected so you never reach for credit; the target is 3 to 6 months of essential expenses, and it is Step 4 of the Financial Order of Operations
- Why it matters: most derailments start with one surprise bill charged at 20 to 24% interest; Housel frames the fund as buying options, not earning a return
- Essential expenses baseline: housing, groceries, utilities, transportation, health, and minimum debt payments; dining out and subscriptions do not count
- Adjusting for risk: stable income with good coverage needs 3 to 4 months; dependents need 6 minimum; variable or self-employed income leans toward 6 to 9
- Starter fund first: build $1,000, clear high-interest debt, then fill the full 3 to 6 month fund
- Where to keep it: a high-yield savings account, money market fund, or insured credit union; not checking, stocks, long-term CDs, or cash at home
- Why not the stock market: job losses and market drops tend to arrive together; Felix treats the fund as a hedge on human capital
- Building it: 12 to 24 months is typical; doubling the contribution roughly halves the time; automate a payday transfer and find money in small cuts
- Rebuilding: a withdrawal is the fund doing its job; resume contributions immediately without pausing retirement savings
- Emergency fund math: target amount, months to reach the target, contribution needed by a deadline, and what the fund earns while you build it
2 Your Target Amount
Your target is your essential monthly expenses multiplied by the number of months you want to cover. Each extra month adds one more block of expenses.
Formula: Target = Monthly Essential Expenses × Months of Coverage
Book example: $3,500/month in essential expenses × 4 months = $14,000. The 3 and 6 month targets are $10,500 and $21,000.
2.1 Level 1: Guided
Fill in the blanks to finish emergency_fund_target(), then find the target for $3,500 of essential expenses and 4 months of coverage.
Put essential expenses in A2 (3500) and months in B2 (4). Find the target in C2.
=A2 * B2This returns $14,000.
One block of expenses for every month you want covered.
def emergency_fund_target(monthly_expenses, months=3):
return monthly_expenses * months
emergency_fund_target(3500, months=4)One block of expenses for every month you want covered.
emergency_fund_target <- function(monthly_expenses, months = 3) {
monthly_expenses * months
}
emergency_fund_target(3500, months = 4)2.2 Level 2: Practice
Build the essential expenses from the book’s baseline (housing $1,600, groceries $550, utilities $300, transportation $600, health $250, minimum debt payments $200), then find a 6-month target.
Put the categories in A2:A7 and amounts in B2:B7. Find the 6-month target in one formula.
=SUM(B2:B7) * 6Essentials total $3,500, so the target is $21,000.
Add up the amount column with .sum().
monthly = essentials["amount"].sum()
emergency_fund_target(monthly, months=6)Add up the amount column with sum().
essentials |>
summarise(monthly = sum(amount)) |>
mutate(target = emergency_fund_target(monthly, months = 6)) |>
pull(target)2.3 Level 3: Challenge
Risk sets the months: stable income needs 4, dependents need 6, and self-employed income needs 9. Find the target for each household below.
| Household | Essentials | Situation |
|---|---|---|
| A | $2,500 | Stable |
| B | $3,500 | Dependents |
| C | $5,000 | Self-employed |
Put essentials in B2:B4 and the situation in C2:C4. Find each target in D.
In D2, then fill down:
=B2 * SWITCH(C2, "Stable", 4, "Dependents", 6, "Self-employed", 9)The targets are $10,000, $21,000, and $45,000.
households["situation"].map({"Stable": 4, "Dependents": 6, "Self-employed": 9}) turns each label into months. Return the target column as a list with .tolist().
households["months"] = households["situation"].map({"Stable": 4, "Dependents": 6, "Self-employed": 9})
households["target"] = emergency_fund_target(households["essentials"], households["months"])
households["target"].tolist()Inside mutate(), use case_when(situation == "Stable" ~ 4, ...) for months, then emergency_fund_target(essentials, months). Finish with pull(target).
households |>
mutate(
months = case_when(
situation == "Stable" ~ 4,
situation == "Dependents" ~ 6,
situation == "Self-employed" ~ 9
),
target = emergency_fund_target(essentials, months)
) |>
pull(target)3 Months to Reach Your Target
Given your current balance and a monthly contribution, how long until you reach the target? Part of the target bar is already filled; the monthly contributions close the gap.
Formula: Months to Goal = (Target − Current Balance) ÷ Monthly Contribution
Book example: a $14,000 target with $2,000 saved and $500/month takes (14,000 − 2,000) ÷ 500 = 24 months.
3.1 Level 1: Guided
Fill in the blanks to finish months_to_ef_goal(), then find how long it takes to reach $14,000 with $2,000 saved and $500 a month.
Put the target in A2 (14000), the balance in B2 (2000), and the contribution in C2 (500). Find the whole months in D2.
=ROUNDUP(MAX(0, A2 - B2) / C2, 0)This returns 24.
What’s left is the target minus what you already have.
import math
def months_to_ef_goal(target, current_balance, monthly_contribution):
remaining = max(0, target - current_balance)
return math.ceil(remaining / monthly_contribution)
months_to_ef_goal(14000, 2000, 500)What’s left is the target minus what you already have.
months_to_ef_goal <- function(target, current_balance, monthly_contribution) {
remaining <- max(0, target - current_balance)
ceiling(remaining / monthly_contribution)
}
months_to_ef_goal(14000, 2000, 500)3.2 Level 2: Practice
Double the contribution to $1,000 a month. How many months now?
Change C2 to 1000.
The same formula returns 12. Doubling the contribution halves the wait.
Same target and balance, new contribution.
months_to_ef_goal(14000, 2000, 1000)Same target and balance, new contribution.
months_to_ef_goal(14000, 2000, 1000)3.3 Level 3: Challenge
You want the $14,000 fund done in 18 months or less, starting from $2,000. Contributions come in $50 steps from $300 to $1,000. What is the smallest one that finishes in time?
Put $300 to $1,000 in steps of 50 in A5:A19, the months for each in B5:B19, and find the smallest contribution that takes 18 months or less.
In B5, filled down: =ROUNDUP((14000-2000)/A5, 0). Then:
=MINIFS(A5:A19, B5:B19, "<=18")The answer is $700 (18 months; $650 takes 19).
Use min(c for c in contributions if months_to_ef_goal(14000, 2000, c) <= 18).
contributions = range(300, 1001, 50)
min(c for c in contributions if months_to_ef_goal(14000, 2000, c) <= 18)The contribution argument is vectorized, so months_to_ef_goal(14000, 2000, contributions) gives all the months at once. Then min(contributions[...]).
contributions <- seq(300, 1000, by = 50)
months <- months_to_ef_goal(14000, 2000, contributions)
min(contributions[months <= 18])4 Contribution Needed by a Deadline
Working backwards: to reach the target by a set month, how much do you need to save each month? The number of slices is fixed, and the question is how wide each slice must be.
Formula: Monthly Contribution = (Target − Current Balance) ÷ Months Remaining
Book example: a $14,000 fund in 18 months with $2,000 saved needs (14,000 − 2,000) ÷ 18 = $667/month.
4.1 Level 1: Guided
Fill in the blanks to finish monthly_contribution_needed(), then find the monthly amount to build $14,000 in 18 months with $2,000 saved.
Put the target in A2 (14000), the balance in B2 (2000), and the months in C2 (18). Find the monthly amount in D2, rounded up to the dollar.
=ROUNDUP(MAX(0, A2 - B2) / C2, 0)This returns $667.
Split what’s left evenly across the months.
import math
def monthly_contribution_needed(target, current_balance, months):
remaining = max(0, target - current_balance)
return math.ceil(remaining / months)
monthly_contribution_needed(14000, 2000, 18)Split what’s left evenly across the months.
monthly_contribution_needed <- function(target, current_balance, months) {
remaining <- max(0, target - current_balance)
ceiling(remaining / months)
}
monthly_contribution_needed(14000, 2000, 18)4.2 Level 2: Practice
$667 doesn’t fit the budget. Stretch the deadline to 24 months. What is the monthly amount now?
Change C2 to 24.
The same formula returns $500.
Same target and balance, 24 months.
monthly_contribution_needed(14000, 2000, 24)Same target and balance, 24 months.
monthly_contribution_needed(14000, 2000, 24)4.3 Level 3: Challenge
The fund sits in a 4.5% high-yield account while you build it, so interest does some of the work. Write contribution_with_interest(target, current_balance, annual_rate, months) and find the monthly amount to reach $14,000 in 18 months from $2,000. The formula is (Target − Balance × (1 + r)^n) × r ÷ ((1 + r)^n − 1), with r = annual rate ÷ 12.
Find the monthly amount in one formula.
=PMT(4.5%/12, 18, -2000, 14000)This returns about $638.17, about $29 a month less than ignoring interest. (Excel shows it as negative because it is money leaving your pocket.)
Set monthly_rate = annual_rate / 12 and growth = (1 + monthly_rate) ** months, then return (target - current_balance * growth) * monthly_rate / (growth - 1).
def contribution_with_interest(target, current_balance, annual_rate, months):
monthly_rate = annual_rate / 12
growth = (1 + monthly_rate) ** months
return (target - current_balance * growth) * monthly_rate / (growth - 1)
contribution_with_interest(14000, 2000, 0.045, 18)Set monthly_rate <- annual_rate / 12 and growth <- (1 + monthly_rate)^months, then return (target - current_balance * growth) * monthly_rate / (growth - 1).
contribution_with_interest <- function(target, current_balance, annual_rate, months) {
monthly_rate <- annual_rate / 12
growth <- (1 + monthly_rate)^months
(target - current_balance * growth) * monthly_rate / (growth - 1)
}
contribution_with_interest(14000, 2000, 0.045, 18)5 What the Fund Earns While You Build It
A fund in a high-yield savings account earns interest. It will not change your timeline much, but it is real money. Each month the balance is multiplied by (1 + the monthly rate).
Formula: Future Value = Balance × (1 + monthly rate)^months, where monthly rate = annual rate ÷ 12
Book example: $14,000 at 4.5%, untouched for 12 months, grows to about $14,643.
5.1 Level 1: Guided
Fill in the blanks to finish ef_growth(), then find what $14,000 grows to in 12 months at 4.5%.
Put the balance in A2 (14000), the rate in B2 (0.045), and months in C2 (12). Find the balance in D2.
=A2*(1+B2/12)^C2This returns $14,643.16.
Split the yearly rate across 12 months, then compound once per month.
def ef_growth(balance, annual_rate, months):
monthly_rate = annual_rate / 12
return balance * (1 + monthly_rate) ** months
ef_growth(14000, 0.045, 12)Split the yearly rate across 12 months, then compound once per month.
ef_growth <- function(balance, annual_rate, months) {
monthly_rate <- annual_rate / 12
balance * (1 + monthly_rate)^months
}
ef_growth(14000, 0.045, 12)5.2 Level 2: Practice
A big bank savings account pays 0.01%. Over 12 months, how much more interest does the 4.5% high-yield account earn on $14,000?
Find both interest amounts and the difference.
=(14000*(1+4.5%/12)^12 - 14000) - (14000*(1+0.01%/12)^12 - 14000)This returns about $641.76. The big bank pays about $1.40.
Write 0.01% as 0.0001.
hysa = ef_growth(14000, 0.045, 12) - 14000
big_bank = ef_growth(14000, 0.0001, 12) - 14000
hysa - big_bankWrite 0.01% as 0.0001.
hysa <- ef_growth(14000, 0.045, 12) - 14000
big_bank <- ef_growth(14000, 0.0001, 12) - 14000
hysa - big_bank5.3 Level 3: Challenge
A surprise $300 car repair is coming. At 4.5%, after how many whole months has the $14,000 fund earned at least $300 of interest?
Put months 1 to 24 in A5:A28, find the interest at each month in B, then find the first month at or above $300.
In B5, filled down: =14000*(1+4.5%/12)^A5 - 14000. Then:
=MATCH(TRUE, B5:B28>=300, 0)The answer is 6 months.
Use while ef_growth(14000, 0.045, months) - 14000 < 300: and add 1 to months inside the loop.
months = 1
while ef_growth(14000, 0.045, months) - 14000 < 300:
months += 1
monthsef_growth() is vectorized: pass all 24 months, subtract 14000, and use min(months[...]).
months <- 1:24
interest <- ef_growth(14000, 0.045, months) - 14000
min(months[interest >= 300])






