1
0
mirror of https://github.com/elisspace/own_vs_buy.git synced 2026-08-29 15:44:04 +00:00
Files
own_vs_buy/own_vs_buy2.py
2025-02-11 15:34:38 -05:00

234 lines
8.7 KiB
Python

def main():
"""
1. Prints assumption values.
2. Calculates monthly living expenses (inflation-adjusted) for groceries, travel, schooling, healthcare, incidentals.
3. Calculates renting vs buying costs each month (both in terms of cash flow and net worth).
4. Compares the final net worth of renting vs buying, color-codes the final statement to indicate which is better.
"""
# ANSI color codes for terminal output
COLOR_GREEN = "\033[92m"
COLOR_RED = "\033[91m"
COLOR_RESET = "\033[0m"
COLOR_YELLOW = "\033[93m" # optional for neutral or headings
# ================
# Part 1: Constants
# ================
# Time horizon
CURRENT_AGE = 35
AGE_AT_DEATH = 90
total_years = AGE_AT_DEATH - CURRENT_AGE
total_months = total_years * 12
# --- Income & Growth ---
MONTHLY_SALARY = 5000.0 # Initial monthly salary
ANNUAL_SALARY_GROWTH = 0.02 # 2% annual salary increase
# --- Inflation for Monthly Expenses ---
ANNUAL_INFLATION = 0.03 # 3% annual
# --- Base Monthly Expenses (excluding accommodation) ---
BASE_GROCERIES = 500.0
BASE_TRAVEL = 200.0
BASE_SCHOOLING = 300.0
BASE_HEALTHCARE = 400.0
BASE_INCIDENTALS = 2500 # "catch-all" category
# --- Investment Growth ---
ANNUAL_INVESTMENT_RETURN = 0.06 # 6% annual
# --- Renting Details ---
RENT_PER_MONTH = 1500.0
ANNUAL_RENT_GROWTH = 0.025 # 2.5% annual
# --- Buying Details ---
HOME_COST = 350_000.0
DOWN_PAYMENT = 80_000.0
BUYER_CLOSING_COSTS = 5_000.0
MORTGAGE_RATE = 0.04 # 4% annual
MORTGAGE_TERM_YEARS = 30
PROPERTY_TAX_RATE = 0.01 # 1% of home value per year
HOME_INSURANCE_PER_YEAR = 1200.0
AVERAGE_YEARLY_MAINTENANCE = 5000.0
# Home appreciation (positive or negative)
ANNUAL_HOME_APPRECIATION = 0.02 # 2% per year
# ================
# Display Assumptions
# ================
print(f"{COLOR_YELLOW}----- Assumptions -----{COLOR_RESET}")
print(f"Time Span: {CURRENT_AGE} to {AGE_AT_DEATH} (Total {total_years} years)")
print(f"Initial Monthly Salary: ${MONTHLY_SALARY:,.2f}")
print(f"Annual Salary Growth: {ANNUAL_SALARY_GROWTH*100:.2f}%")
print(f"Annual Inflation (non-housing expenses): {ANNUAL_INFLATION*100:.2f}%")
print(f"Base Monthly Expenses (Groceries + Travel + Schooling + Healthcare + Incidentals): "
f"${(BASE_GROCERIES + BASE_TRAVEL + BASE_SCHOOLING + BASE_HEALTHCARE + BASE_INCIDENTALS):,.2f}")
print(f"Annual Investment Return: {ANNUAL_INVESTMENT_RETURN*100:.2f}%\n")
print("Renting Assumptions:")
print(f" - Initial Monthly Rent: ${RENT_PER_MONTH:,.2f}")
print(f" - Annual Rent Growth: {ANNUAL_RENT_GROWTH*100:.2f}%\n")
print("Buying Assumptions:")
print(f" - Home Cost: ${HOME_COST:,.2f}")
print(f" - Down Payment: ${DOWN_PAYMENT:,.2f}")
print(f" - Buyer Closing Costs: ${BUYER_CLOSING_COSTS:,.2f}")
print(f" - Mortgage Rate (Annual): {MORTGAGE_RATE*100:.2f}%")
print(f" - Mortgage Term: {MORTGAGE_TERM_YEARS} years")
print(f" - Property Tax Rate: {PROPERTY_TAX_RATE*100:.2f}% of home value/year")
print(f" - Home Insurance/Year: ${HOME_INSURANCE_PER_YEAR:,.2f}")
print(f" - Avg Yearly Maintenance: ${AVERAGE_YEARLY_MAINTENANCE:,.2f}")
print(f" - Annual Home Appreciation: {ANNUAL_HOME_APPRECIATION*100:.2f}%")
print(f"{'-'*50}\n")
# ================
# Part 2: Derive Monthly Rates and Setup
# ================
monthly_salary_growth = (1 + ANNUAL_SALARY_GROWTH) ** (1/12) - 1
monthly_inflation = (1 + ANNUAL_INFLATION) ** (1/12) - 1
monthly_investment_growth = ANNUAL_INVESTMENT_RETURN / 12
monthly_rent_growth = (1 + ANNUAL_RENT_GROWTH) ** (1/12) - 1
monthly_home_appreciation = (1 + ANNUAL_HOME_APPRECIATION) ** (1/12) - 1
# Base standard expenses total
base_standard_expenses = (
BASE_GROCERIES +
BASE_TRAVEL +
BASE_SCHOOLING +
BASE_HEALTHCARE +
BASE_INCIDENTALS
)
current_standard_expenses = base_standard_expenses
# Mortgage payment
principal = HOME_COST - DOWN_PAYMENT
monthly_mortgage_rate = MORTGAGE_RATE / 12
number_of_payments = MORTGAGE_TERM_YEARS * 12
if principal > 0:
monthly_mortgage_payment = (
principal *
(monthly_mortgage_rate * (1 + monthly_mortgage_rate) ** number_of_payments) /
((1 + monthly_mortgage_rate) ** number_of_payments - 1)
)
else:
monthly_mortgage_payment = 0.0
monthly_property_tax = (HOME_COST * PROPERTY_TAX_RATE) / 12
monthly_insurance = HOME_INSURANCE_PER_YEAR / 12
monthly_maintenance = AVERAGE_YEARLY_MAINTENANCE / 12
# ================
# Part 3: Tracking & Simulation
# ================
total_income = 0.0
total_standard_expenses_accum = 0.0
# Renting scenario
total_rent_cost = 0.0
rent_investment_balance = DOWN_PAYMENT + BUYER_CLOSING_COSTS # Freed up capital if you don't buy
current_rent = RENT_PER_MONTH
# Buying scenario
total_buy_cost = DOWN_PAYMENT + BUYER_CLOSING_COSTS # upfront cost
buy_investment_balance = 0.0
house_value = HOME_COST
# Starting salary
current_monthly_salary = MONTHLY_SALARY
for month in range(1, total_months + 1):
# --- Income
total_income += current_monthly_salary
# --- Standard Expenses (inflation-adjusted)
total_standard_expenses_accum += current_standard_expenses
# --- Renting: Pay Rent, Invest Leftover
total_rent_cost += current_rent
leftover_rent = current_monthly_salary - current_standard_expenses - current_rent
if leftover_rent > 0:
rent_investment_balance += leftover_rent
rent_investment_balance *= (1 + monthly_investment_growth)
# --- Buying: Pay Mortgage/Costs, Invest Leftover
if month <= number_of_payments:
monthly_ownership_cost = (
monthly_mortgage_payment +
monthly_property_tax +
monthly_insurance +
monthly_maintenance
)
else:
monthly_ownership_cost = (
monthly_property_tax +
monthly_insurance +
monthly_maintenance
)
total_buy_cost += monthly_ownership_cost
leftover_buy = current_monthly_salary - current_standard_expenses - monthly_ownership_cost
if leftover_buy > 0:
buy_investment_balance += leftover_buy
buy_investment_balance *= (1 + monthly_investment_growth)
# House Appreciation
house_value *= (1 + monthly_home_appreciation)
# Increase Salary, Rent, Standard Expenses (monthly growth)
current_monthly_salary *= (1 + monthly_salary_growth)
current_rent *= (1 + monthly_rent_growth)
current_standard_expenses *= (1 + monthly_inflation)
# ================
# Part 4: Final Output & Comparison
# ================
print(f"{COLOR_YELLOW}----- Final Results -----{COLOR_RESET}")
print(f"Total Income (All Sources): ${total_income:,.2f}")
print(f"Total Standard Expenses (Excl. Accommodation): ${total_standard_expenses_accum:,.2f}")
# Costs including renting
total_rent_incl_expenses = total_standard_expenses_accum + total_rent_cost
print(f"Total Costs (Incl. Rent): ${total_rent_incl_expenses:,.2f}")
# Costs including buying
total_buy_incl_expenses = total_standard_expenses_accum + total_buy_cost
print(f"Total Costs (Incl. Buy): ${total_buy_incl_expenses:,.2f}\n")
# Compute a simplified 'final net worth' approach
# - Renter's net worth: final investment balance
# - Owner's net worth: final investment balance + house value
rent_net_worth = rent_investment_balance
buy_net_worth = buy_investment_balance + house_value
print(f"Renter's Final Investment Balance: ${rent_net_worth:,.2f}")
print(f"Homeowner's Investment Balance: ${buy_investment_balance:,.2f}")
print(f"Final House Value: ${house_value:,.2f}")
print()
difference = buy_net_worth - rent_net_worth
if difference > 0:
# Buying scenario is ahead
print(
f"{COLOR_GREEN}Buying is ahead by ${difference:,.2f} "
f"({buy_net_worth:,.2f} vs. {rent_net_worth:,.2f}){COLOR_RESET}"
)
elif difference < 0:
# Renting scenario is ahead
print(
f"{COLOR_GREEN}Renting is ahead by ${abs(difference):,.2f} "
f"({rent_net_worth:,.2f} vs. {buy_net_worth:,.2f}){COLOR_RESET}"
)
else:
# Exactly the same (unlikely in real life)
print(f"{COLOR_YELLOW}Both scenarios come out exactly the same!{COLOR_RESET}")
if __name__ == "__main__":
main()