Debt Snowball Calculator
Plan your debt payoff using Snowball or Avalanche strategy with payoff timeline.
Frequently Asked Questions
Code Implementation
from dataclasses import dataclass, field
from typing import List, Optional
@dataclass
class Debt:
name: str
balance: float
min_payment: float
apr: float # Annual Percentage Rate e.g. 0.20 for 20%
@property
def monthly_rate(self) -> float:
return self.apr / 12
@dataclass
class PayoffResult:
name: str
months_to_payoff: int
total_paid: float
total_interest: float
def debt_snowball(debts: List[Debt], monthly_budget: float) -> List[PayoffResult]:
"""
Simulate the debt snowball method.
Debts are sorted by balance (smallest first).
Extra budget is applied to the current target debt.
"""
# Sort by balance ascending (snowball)
queue = sorted(debts, key=lambda d: d.balance)
paid = [False] * len(queue)
bals = [d.balance for d in queue]
totals = [0.0] * len(queue) # total paid per debt
month = 0
results = []
while any(not p for p in paid):
month += 1
# Find current target: first unpaid debt
target_idx = next(i for i, p in enumerate(paid) if not p)
# Calculate total minimums for non-target debts
minimums_used = sum(
queue[i].min_payment for i in range(len(queue))
if not paid[i] and i != target_idx
)
extra = monthly_budget - minimums_used
# Apply payments
for i, debt in enumerate(queue):
if paid[i]:
continue
payment = extra if i == target_idx else debt.min_payment
interest = bals[i] * debt.monthly_rate
principal = min(payment - interest, bals[i])
bals[i] -= principal
totals[i] += payment
if bals[i] <= 0.01:
paid[i] = True
results.append(PayoffResult(
name=debt.name,
months_to_payoff=month,
total_paid=totals[i] + bals[i], # adjust overpayment
total_interest=totals[i] - debt.balance
))
return results
# Example
debts = [
Debt("Credit Card A", balance=2500, min_payment=75, apr=0.22),
Debt("Credit Card B", balance=5000, min_payment=100, apr=0.18),
Debt("Car Loan", balance=8000, min_payment=200, apr=0.06),
Debt("Student Loan", balance=15000, min_payment=150, apr=0.05),
]
results = debt_snowball(debts, monthly_budget=700)
total_interest = sum(r.total_interest for r in results)
print("Debt Snowball Payoff Plan:")
print(f"{'Debt':<20} {'Months':>7} {'Interest Paid':>14}")
for r in results:
yrs = r.months_to_payoff // 12
mos = r.months_to_payoff % 12
print(f"{r.name:<20} {yrs}y {mos:02d}m ${r.total_interest:>12,.2f}")
print(f"{'Total interest:':<20} ${total_interest:>12,.2f}")
Comments & Feedback
Comments are powered by Giscus. Sign in with GitHub to leave a comment.