mirror of
https://github.com/elisspace/own_vs_buy.git
synced 2026-08-29 15:44:04 +00:00
new branch building on lessons learned
This commit is contained in:
161
app.py
161
app.py
@@ -1,161 +0,0 @@
|
||||
from flask import Flask, render_template, request, redirect, url_for, session, jsonify
|
||||
|
||||
app = Flask(__name__)
|
||||
app.secret_key = 'SUPER-SECRET-KEY' # Replace with something more secure in production
|
||||
|
||||
# Demo user dictionary (store hashed credentials in a real system)
|
||||
USERS = {
|
||||
"testuser": "testpass"
|
||||
}
|
||||
|
||||
@app.route('/', methods=['GET', 'POST'])
|
||||
def login():
|
||||
if request.method == 'POST':
|
||||
username = request.form.get('username')
|
||||
password = request.form.get('password')
|
||||
if USERS.get(username) == password:
|
||||
session['logged_in'] = True
|
||||
return redirect(url_for('calculator'))
|
||||
else:
|
||||
return render_template('login.html', error="Invalid username/password.")
|
||||
else:
|
||||
if session.get('logged_in'):
|
||||
return redirect(url_for('calculator'))
|
||||
return render_template('login.html')
|
||||
|
||||
@app.route('/logout')
|
||||
def logout():
|
||||
session.clear()
|
||||
return redirect(url_for('login'))
|
||||
|
||||
@app.route('/calculator')
|
||||
def calculator():
|
||||
if not session.get('logged_in'):
|
||||
return redirect(url_for('login'))
|
||||
return render_template('calculator.html')
|
||||
|
||||
@app.route('/compute', methods=['POST'])
|
||||
def compute():
|
||||
"""
|
||||
AJAX endpoint that receives user inputs (via JSON),
|
||||
then calculates renting vs. buying outcomes.
|
||||
This version dynamically updates taxes, insurance,
|
||||
and maintenance based on the house's changing value.
|
||||
"""
|
||||
data = request.json
|
||||
|
||||
# User inputs
|
||||
current_age = float(data.get('current_age', 30))
|
||||
age_at_death = float(data.get('age_at_death', 90))
|
||||
monthly_salary = float(data.get('monthly_salary', 5000))
|
||||
monthly_rent = float(data.get('monthly_rent', 1500))
|
||||
home_cost = float(data.get('home_cost', 400000))
|
||||
down_payment = float(data.get('down_payment', 80000))
|
||||
monthly_expenses = float(data.get('monthly_expenses', 1500))
|
||||
investment_return = float(data.get('investment_return', 6)) / 100.0
|
||||
|
||||
# Time horizon
|
||||
years = age_at_death - current_age
|
||||
months = int(years * 12)
|
||||
|
||||
# Simple monthly investment rate
|
||||
monthly_investment_rate = investment_return / 12
|
||||
|
||||
# ------------------
|
||||
# Renter Scenario
|
||||
# ------------------
|
||||
# Start with a lump sum (down payment) in investments
|
||||
renter_investment_balance = down_payment
|
||||
current_monthly_salary = monthly_salary
|
||||
|
||||
# We won't change rent monthly here in detail,
|
||||
# but you could add rent growth if desired.
|
||||
# For now, keep it fixed for simplicity.
|
||||
|
||||
for _ in range(months):
|
||||
leftover_rent = current_monthly_salary - (monthly_rent + monthly_expenses)
|
||||
if leftover_rent > 0:
|
||||
renter_investment_balance += leftover_rent
|
||||
# Grow investment
|
||||
renter_investment_balance *= (1 + monthly_investment_rate)
|
||||
|
||||
# We’ll skip monthly salary growth to keep it straightforward
|
||||
# but you could easily incorporate that as well.
|
||||
|
||||
renter_net_worth = renter_investment_balance
|
||||
|
||||
# ------------------
|
||||
# Buyer Scenario
|
||||
# ------------------
|
||||
# Mortgage logic: Very simplified example
|
||||
principal = home_cost - down_payment
|
||||
mortgage_rate_annual = 0.04 # 4% annual, for demonstration
|
||||
monthly_mortgage_rate = mortgage_rate_annual / 12
|
||||
mortgage_term_years = 30
|
||||
num_payments = mortgage_term_years * 12
|
||||
|
||||
if principal > 0:
|
||||
# Standard formula
|
||||
monthly_mortgage_payment = (
|
||||
principal *
|
||||
(monthly_mortgage_rate * (1 + monthly_mortgage_rate) ** num_payments) /
|
||||
((1 + monthly_mortgage_rate) ** num_payments - 1)
|
||||
)
|
||||
else:
|
||||
monthly_mortgage_payment = 0
|
||||
|
||||
# Let's assume a 1% property tax and 0.3% insurance, 0.2% maintenance, all annual,
|
||||
# but it will scale with changing house value
|
||||
property_tax_annual_rate = 0.01
|
||||
insurance_annual_rate = 0.003
|
||||
maintenance_annual_rate = 0.002
|
||||
|
||||
# House appreciation
|
||||
annual_appreciation_rate = 0.02 # 2% annual
|
||||
monthly_appreciation_rate = annual_appreciation_rate / 12
|
||||
|
||||
house_value = home_cost
|
||||
buyer_investment_balance = 0
|
||||
total_upfront = down_payment # ignoring closing costs for simplicity here
|
||||
|
||||
for month_index in range(months):
|
||||
# Each month, update the house value first
|
||||
house_value *= (1 + monthly_appreciation_rate)
|
||||
|
||||
# Recalc these costs based on the updated house value
|
||||
monthly_taxes = (house_value * property_tax_annual_rate) / 12
|
||||
monthly_insurance = (house_value * insurance_annual_rate) / 12
|
||||
monthly_maintenance = (house_value * maintenance_annual_rate) / 12
|
||||
|
||||
# If mortgage is still active
|
||||
if month_index < num_payments:
|
||||
monthly_costs = monthly_mortgage_payment + monthly_taxes + monthly_insurance + monthly_maintenance
|
||||
else:
|
||||
monthly_costs = monthly_taxes + monthly_insurance + monthly_maintenance
|
||||
|
||||
leftover_buy = monthly_salary - (monthly_expenses + monthly_costs)
|
||||
if leftover_buy > 0:
|
||||
buyer_investment_balance += leftover_buy
|
||||
|
||||
# Grow leftover investment
|
||||
buyer_investment_balance *= (1 + monthly_investment_rate)
|
||||
|
||||
homeowner_net_worth = buyer_investment_balance + house_value
|
||||
|
||||
# Compare
|
||||
difference = homeowner_net_worth - renter_net_worth
|
||||
|
||||
results = {
|
||||
"renter_investment_balance": f"${renter_investment_balance:,.2f}",
|
||||
"homeowner_investment_balance": f"${buyer_investment_balance:,.2f}",
|
||||
"final_house_value": f"${house_value:,.2f}",
|
||||
"homeowner_net_worth": f"${homeowner_net_worth:,.2f}",
|
||||
"renter_net_worth": f"${renter_net_worth:,.2f}",
|
||||
"difference": difference
|
||||
}
|
||||
|
||||
return jsonify(results)
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(debug=True, host='0.0.0.0')
|
||||
|
||||
160
calculator.py
Normal file
160
calculator.py
Normal file
@@ -0,0 +1,160 @@
|
||||
import math
|
||||
|
||||
def calculate_mortgage_payment(principal, annual_interest_rate, term_years):
|
||||
"""Calculates the fixed monthly mortgage payment."""
|
||||
monthly_rate = annual_interest_rate / 12
|
||||
n = term_years * 12
|
||||
if monthly_rate == 0:
|
||||
return principal / n
|
||||
payment = principal * monthly_rate / (1 - (1 + monthly_rate) ** (-n))
|
||||
return payment
|
||||
|
||||
def simulate_own_vs_rent(params):
|
||||
# Extract parameters with defaults (as provided)
|
||||
start_age = params.get("start_age", 30)
|
||||
end_age = params.get("end_age", 65)
|
||||
total_months = (end_age - start_age) * 12
|
||||
|
||||
annual_income = params.get("annual_income", 60000)
|
||||
annual_salary_growth = params.get("annual_salary_growth", 0.02)
|
||||
home_price = params.get("home_price", 300000)
|
||||
down_payment = params.get("down_payment", 60000)
|
||||
mortgage_rate = params.get("mortgage_rate", 0.04)
|
||||
mortgage_term = params.get("mortgage_term", 30)
|
||||
property_tax_rate = params.get("property_tax_rate", 0.012)
|
||||
homeowner_insurance = params.get("homeowner_insurance", 1200)
|
||||
maintenance_rate = params.get("maintenance_rate", 0.01)
|
||||
rent = params.get("rent", 1500)
|
||||
rent_escalation_rate = params.get("rent_escalation_rate", 0.03)
|
||||
renters_insurance_annual = params.get("renters_insurance_annual", 240) # ~$20/month
|
||||
home_appreciation = params.get("home_appreciation", 0.03)
|
||||
investment_return = params.get("investment_return", 0.05)
|
||||
marginal_tax_rate = params.get("marginal_tax_rate", 0.25)
|
||||
inflation_rate = params.get("inflation_rate", 0.02)
|
||||
|
||||
# Monthly conversion factors (using monthly compounding approximations)
|
||||
monthly_salary_growth = (1 + annual_salary_growth) ** (1/12) - 1
|
||||
monthly_investment_return = (1 + investment_return) ** (1/12) - 1
|
||||
monthly_home_appreciation = (1 + home_appreciation) ** (1/12) - 1
|
||||
monthly_rent_escalation = (1 + rent_escalation_rate) ** (1/12) - 1
|
||||
|
||||
# Initialize simulation variables
|
||||
salary = annual_income
|
||||
current_home_value = home_price
|
||||
mortgage_balance = home_price - down_payment
|
||||
mortgage_payment = calculate_mortgage_payment(mortgage_balance, mortgage_rate, mortgage_term)
|
||||
mortgage_term_months = mortgage_term * 12
|
||||
|
||||
homeowner_investment = 0.0
|
||||
renter_investment = down_payment # down payment is invested in the renting scenario
|
||||
homeowner_debt = 0.0
|
||||
renter_debt = 0.0
|
||||
lifetime_income = 0.0
|
||||
|
||||
# For rent, we will update the current monthly rent over time
|
||||
current_rent = rent
|
||||
|
||||
# Simulation loop (month by month)
|
||||
for month in range(1, total_months + 1):
|
||||
# Update lifetime income (monthly)
|
||||
monthly_income = salary / 12
|
||||
lifetime_income += monthly_income
|
||||
|
||||
# --- Homeowner Scenario ---
|
||||
if month <= mortgage_term_months:
|
||||
# Calculate current month's mortgage payment details
|
||||
monthly_interest = mortgage_balance * (mortgage_rate / 12)
|
||||
principal_payment = mortgage_payment - monthly_interest
|
||||
# Adjust final payment if necessary
|
||||
if principal_payment > mortgage_balance:
|
||||
principal_payment = mortgage_balance
|
||||
mortgage_payment = monthly_interest + principal_payment
|
||||
mortgage_balance -= principal_payment
|
||||
else:
|
||||
mortgage_payment = 0
|
||||
monthly_interest = 0
|
||||
|
||||
monthly_property_tax = (current_home_value * property_tax_rate) / 12
|
||||
monthly_insurance = homeowner_insurance / 12
|
||||
monthly_maintenance = (current_home_value * maintenance_rate) / 12
|
||||
|
||||
# Tax benefit applies only when mortgage (and its interest) is active.
|
||||
tax_benefit = 0
|
||||
if month <= mortgage_term_months:
|
||||
tax_benefit = (monthly_interest + monthly_property_tax) * marginal_tax_rate
|
||||
|
||||
homeowner_cost = mortgage_payment + monthly_property_tax + monthly_insurance + monthly_maintenance - tax_benefit
|
||||
|
||||
# --- Renting Scenario ---
|
||||
monthly_rent = current_rent
|
||||
renters_insurance = renters_insurance_annual / 12
|
||||
renting_cost = monthly_rent + renters_insurance
|
||||
|
||||
# --- Surplus Cash Flow ---
|
||||
homeowner_surplus = monthly_income - homeowner_cost
|
||||
renter_surplus = monthly_income - renting_cost
|
||||
|
||||
# Update investment balances (if surplus positive) or accumulate debt (if negative)
|
||||
if homeowner_surplus >= 0:
|
||||
homeowner_investment = homeowner_investment * (1 + monthly_investment_return) + homeowner_surplus
|
||||
else:
|
||||
# Debt grows with the effective investment rate
|
||||
homeowner_debt = homeowner_debt * (1 + monthly_investment_return) - homeowner_surplus
|
||||
|
||||
if renter_surplus >= 0:
|
||||
renter_investment = renter_investment * (1 + monthly_investment_return) + renter_surplus
|
||||
else:
|
||||
renter_debt = renter_debt * (1 + monthly_investment_return) - renter_surplus
|
||||
|
||||
# Update home value (appreciation)
|
||||
current_home_value *= (1 + monthly_home_appreciation)
|
||||
|
||||
# Update salary for next month
|
||||
salary *= (1 + monthly_salary_growth)
|
||||
|
||||
# Update rent for next month
|
||||
current_rent *= (1 + monthly_rent_escalation)
|
||||
|
||||
final_house_value = current_home_value
|
||||
|
||||
# Net worth calculations: include investment balance, property value, subtract remaining mortgage and any accumulated debt.
|
||||
homeowner_net_worth = final_house_value + homeowner_investment - mortgage_balance - homeowner_debt
|
||||
renter_net_worth = renter_investment - renter_debt
|
||||
|
||||
results = {
|
||||
"lifetime_income": lifetime_income,
|
||||
"renter_final_investment": renter_investment,
|
||||
"homeowner_final_investment": homeowner_investment,
|
||||
"final_house_value": final_house_value,
|
||||
"homeowner_net_worth": homeowner_net_worth,
|
||||
"renter_net_worth": renter_net_worth,
|
||||
"mortgage_balance": mortgage_balance, # for reference if needed
|
||||
}
|
||||
return results
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Run simulation with default values for testing
|
||||
defaults = {
|
||||
"start_age": 30,
|
||||
"end_age": 65,
|
||||
"annual_income": 60000,
|
||||
"annual_salary_growth": 0.02,
|
||||
"home_price": 300000,
|
||||
"down_payment": 60000,
|
||||
"mortgage_rate": 0.04,
|
||||
"mortgage_term": 30,
|
||||
"property_tax_rate": 0.012,
|
||||
"homeowner_insurance": 1200,
|
||||
"maintenance_rate": 0.01,
|
||||
"rent": 1500,
|
||||
"rent_escalation_rate": 0.03,
|
||||
"renters_insurance_annual": 240,
|
||||
"home_appreciation": 0.03,
|
||||
"investment_return": 0.05,
|
||||
"marginal_tax_rate": 0.25,
|
||||
"inflation_rate": 0.02,
|
||||
}
|
||||
results = simulate_own_vs_rent(defaults)
|
||||
for key, value in results.items():
|
||||
print(f"{key}: {value:.2f}")
|
||||
|
||||
151
own_vs_buy.py
151
own_vs_buy.py
@@ -1,151 +0,0 @@
|
||||
def main():
|
||||
"""
|
||||
Compare lifetime cost of home ownership vs. renting+investing.
|
||||
Incorporates:
|
||||
- House appreciation/depreciation
|
||||
- Down payment and closing costs
|
||||
- Monthly leftover investment if renting is cheaper
|
||||
- Monthly compounding for investment returns
|
||||
"""
|
||||
|
||||
# 1. Define Constants
|
||||
CURRENT_AGE = 35
|
||||
AGE_AT_DEATH = 90
|
||||
|
||||
# Mortgage details
|
||||
MORTGAGE_RATE = 0.04 # 4% annual
|
||||
MORTGAGE_TERM_YEARS = 30
|
||||
HOME_COST = 350_000
|
||||
DOWN_PAYMENT = 50_000
|
||||
BUYER_CLOSING_COSTS = 10_000 # e.g., typical closing fees
|
||||
|
||||
# Home-related costs
|
||||
PROPERTY_TAX_RATE = 0.083 # 1% per year
|
||||
HOME_INSURANCE_PER_YEAR = 1200
|
||||
AVERAGE_YEARLY_MAINTENANCE = 5000
|
||||
|
||||
# House appreciation/depreciation
|
||||
# e.g. 0.02 => +2% per year, -0.02 => -2% per year
|
||||
HOME_APPRECIATION_PERCENT = 0.05
|
||||
|
||||
# Rent details
|
||||
RENT_PER_MONTH = 1500
|
||||
RENT_ANNUAL_GROWTH_RATE = 0.10 # 2.5% per year
|
||||
|
||||
# Investment details
|
||||
INVESTMENT_RETURN_PERCENT = 0.07 # 10% annual
|
||||
|
||||
# 2. Calculate total months for the simulation
|
||||
total_years = AGE_AT_DEATH - CURRENT_AGE
|
||||
total_months = total_years * 12
|
||||
|
||||
# 3. Mortgage Payment Calculation (Monthly)
|
||||
# Formula: M = P * (r(1+r)^n) / ((1+r)^n - 1)
|
||||
# where:
|
||||
# P = (HOME_COST - DOWN_PAYMENT)
|
||||
# r = MORTGAGE_RATE / 12
|
||||
# n = MORTGAGE_TERM_YEARS * 12
|
||||
principal = HOME_COST - DOWN_PAYMENT
|
||||
monthly_interest_rate = MORTGAGE_RATE / 12
|
||||
number_of_payments = MORTGAGE_TERM_YEARS * 12
|
||||
|
||||
if principal > 0:
|
||||
monthly_mortgage_payment = (
|
||||
principal *
|
||||
(monthly_interest_rate * (1 + monthly_interest_rate) ** number_of_payments) /
|
||||
((1 + monthly_interest_rate) ** number_of_payments - 1)
|
||||
)
|
||||
else:
|
||||
# If DOWN_PAYMENT >= HOME_COST, no mortgage needed
|
||||
monthly_mortgage_payment = 0
|
||||
|
||||
# 4. Break down monthly home costs
|
||||
monthly_property_tax = (HOME_COST * PROPERTY_TAX_RATE) / 12
|
||||
monthly_insurance = HOME_INSURANCE_PER_YEAR / 12
|
||||
monthly_maintenance = AVERAGE_YEARLY_MAINTENANCE / 12
|
||||
|
||||
# 5. Initialize tracking variables
|
||||
|
||||
# For the homeowner:
|
||||
# Start with the home’s initial value; it will appreciate monthly
|
||||
house_value = HOME_COST
|
||||
total_ownership_cost = DOWN_PAYMENT + BUYER_CLOSING_COSTS # upfront out-of-pocket
|
||||
|
||||
# For the renter:
|
||||
# Lump sum investment is the down payment + closing costs that aren't spent on buying.
|
||||
investment_balance = DOWN_PAYMENT + BUYER_CLOSING_COSTS
|
||||
total_renting_cost = 0.0
|
||||
|
||||
# Convert annual appreciation to a monthly factor
|
||||
monthly_appreciation_rate = (1 + HOME_APPRECIATION_PERCENT) ** (1/12) - 1
|
||||
|
||||
# Convert annual investment return to monthly
|
||||
monthly_investment_return_rate = INVESTMENT_RETURN_PERCENT / 12
|
||||
|
||||
current_rent = RENT_PER_MONTH
|
||||
|
||||
# 6. Iterate month by month
|
||||
for month in range(1, total_months + 1):
|
||||
# House appreciates each month (can be negative if it's depreciation)
|
||||
house_value *= (1 + monthly_appreciation_rate)
|
||||
|
||||
# Calculate monthly ownership cost
|
||||
if month <= number_of_payments:
|
||||
# Mortgage not fully paid yet
|
||||
monthly_owner_cost = (monthly_mortgage_payment +
|
||||
monthly_property_tax +
|
||||
monthly_insurance +
|
||||
monthly_maintenance)
|
||||
else:
|
||||
# After the mortgage is paid off, only taxes, insurance, and maintenance remain
|
||||
monthly_owner_cost = (monthly_property_tax +
|
||||
monthly_insurance +
|
||||
monthly_maintenance)
|
||||
|
||||
# Add to total ownership cost
|
||||
total_ownership_cost += monthly_owner_cost
|
||||
|
||||
# Renter pays this month’s rent
|
||||
total_renting_cost += current_rent
|
||||
|
||||
# Determine leftover that the renter invests if renting is cheaper
|
||||
# difference > 0 => owning is more expensive => that difference can be invested by the renter
|
||||
difference = monthly_owner_cost - current_rent
|
||||
|
||||
if difference > 0:
|
||||
# This means renting is cheaper by 'difference'
|
||||
investment_balance += difference # invest that difference immediately
|
||||
|
||||
# Grow the investment balance by the monthly return
|
||||
investment_balance *= (1 + monthly_investment_return_rate)
|
||||
|
||||
# Increase rent once a year
|
||||
if month % 12 == 0:
|
||||
current_rent *= (1 + RENT_ANNUAL_GROWTH_RATE)
|
||||
|
||||
# 7. Final net worth calculations
|
||||
# Homeowner's final net worth (simplified):
|
||||
# They own the house, which is now worth house_value.
|
||||
# total_ownership_cost is how much cash was spent over the period (plus the upfront).
|
||||
# You can show them both or compute net_worth as (house_value - total_ownership_cost)
|
||||
net_worth_owning = house_value - total_ownership_cost
|
||||
|
||||
# Renter's final net worth is simply the investment balance
|
||||
net_worth_renting = investment_balance
|
||||
|
||||
# 8. Results
|
||||
print("----- Results -----")
|
||||
print(f"Total Ownership Cost (cash outlay): ${total_ownership_cost:,.2f}")
|
||||
print(f"Final House Value: ${house_value:,.2f}")
|
||||
print(f"Net Worth (Owning) = House Value - Outlays = ${net_worth_owning:,.2f}")
|
||||
print()
|
||||
print(f"Total Rent Paid Over {total_years} Years: ${total_renting_cost:,.2f}")
|
||||
print(f"Final Investment Balance (Renting): ${investment_balance:,.2f}")
|
||||
print(f"Net Worth (Renting) = ${net_worth_renting:,.2f}")
|
||||
print()
|
||||
difference = net_worth_renting - net_worth_owning
|
||||
print(f"Difference (Renting Net Worth - Owning Net Worth): ${difference:,.2f}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
240
own_vs_buy2.py
240
own_vs_buy2.py
@@ -1,240 +0,0 @@
|
||||
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 = 10000.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.0 # "catch-all" category
|
||||
|
||||
# --- Investment Growth ---
|
||||
ANNUAL_INVESTMENT_RETURN = 0.07 # 7% annual
|
||||
|
||||
# --- Renting Details ---
|
||||
RENT_PER_MONTH = 2000.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.05 # 5% 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
|
||||
|
||||
# Convert your annual property tax, insurance, and maintenance to percentage rates relative to HOME_COST:
|
||||
# We'll do this so we can recalculate them each month based on the new house_value.
|
||||
property_tax_annual_rate = PROPERTY_TAX_RATE # e.g., 0.01
|
||||
insurance_annual_rate = HOME_INSURANCE_PER_YEAR / HOME_COST # e.g., 1200 / 350000
|
||||
maintenance_annual_rate = AVERAGE_YEARLY_MAINTENANCE / HOME_COST # e.g., 5000 / 350000
|
||||
|
||||
# ================
|
||||
# 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: Update House Value, then compute monthly taxes, insurance, maintenance
|
||||
house_value *= (1 + monthly_home_appreciation)
|
||||
|
||||
# Recalc monthly property tax, insurance, maintenance based on current house_value
|
||||
dynamic_monthly_property_tax = (house_value * property_tax_annual_rate) / 12
|
||||
dynamic_monthly_insurance = (house_value * insurance_annual_rate) / 12
|
||||
dynamic_monthly_maintenance = (house_value * maintenance_annual_rate) / 12
|
||||
|
||||
if month <= number_of_payments:
|
||||
monthly_ownership_cost = (
|
||||
monthly_mortgage_payment +
|
||||
dynamic_monthly_property_tax +
|
||||
dynamic_monthly_insurance +
|
||||
dynamic_monthly_maintenance
|
||||
)
|
||||
else:
|
||||
monthly_ownership_cost = (
|
||||
dynamic_monthly_property_tax +
|
||||
dynamic_monthly_insurance +
|
||||
dynamic_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)
|
||||
|
||||
# --- 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()
|
||||
|
||||
@@ -1,142 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Rent vs. Buy Calculator</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
}
|
||||
.input-section, .output-section {
|
||||
margin: 20px;
|
||||
}
|
||||
.slider-label {
|
||||
margin-right: 10px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h2>Rent vs. Buy Calculator</h2>
|
||||
<p><a href="/logout">Logout</a></p>
|
||||
|
||||
<div class="input-section">
|
||||
<h3>Input Values</h3>
|
||||
<div>
|
||||
<label for="currentAge">Current Age</label>
|
||||
<input type="range" id="currentAge" min="20" max="70" step="1" value="30" oninput="updateDisplay('currentAgeDisplay', this.value)">
|
||||
<span id="currentAgeDisplay">30</span>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="ageAtDeath">Age at Death</label>
|
||||
<input type="range" id="ageAtDeath" min="70" max="120" step="1" value="90" oninput="updateDisplay('ageAtDeathDisplay', this.value)">
|
||||
<span id="ageAtDeathDisplay">90</span>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="monthlySalary">Monthly Salary</label>
|
||||
<input type="range" id="monthlySalary" min="1000" max="20000" step="500" value="5000" oninput="updateDisplay('monthlySalaryDisplay', this.value)">
|
||||
<span id="monthlySalaryDisplay">5000</span>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="monthlyRent">Monthly Rent</label>
|
||||
<input type="range" id="monthlyRent" min="500" max="4000" step="100" value="1500" oninput="updateDisplay('monthlyRentDisplay', this.value)">
|
||||
<span id="monthlyRentDisplay">1500</span>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="homeCost">Home Cost</label>
|
||||
<input type="range" id="homeCost" min="100000" max="1000000" step="50000" value="400000" oninput="updateDisplay('homeCostDisplay', this.value)">
|
||||
<span id="homeCostDisplay">400000</span>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="downPayment">Down Payment</label>
|
||||
<input type="range" id="downPayment" min="0" max="400000" step="10000" value="80000" oninput="updateDisplay('downPaymentDisplay', this.value)">
|
||||
<span id="downPaymentDisplay">80000</span>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="monthlyExpenses">Monthly Expenses (non-housing)</label>
|
||||
<input type="range" id="monthlyExpenses" min="500" max="5000" step="100" value="1500" oninput="updateDisplay('monthlyExpensesDisplay', this.value)">
|
||||
<span id="monthlyExpensesDisplay">1500</span>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="investmentReturn">Investment Return (%)</label>
|
||||
<input type="range" id="investmentReturn" min="0" max="15" step="0.5" value="6" oninput="updateDisplay('investmentReturnDisplay', this.value)">
|
||||
<span id="investmentReturnDisplay">6</span>%
|
||||
</div>
|
||||
|
||||
<button onclick="calculate()">Calculate</button>
|
||||
</div>
|
||||
|
||||
<div class="output-section">
|
||||
<h3>Results</h3>
|
||||
<p>Renter's Final Investment Balance: <span id="renterInvestment"></span></p>
|
||||
<p>Homeowner's Investment Balance: <span id="homeownerInvestment"></span></p>
|
||||
<p>Final House Value: <span id="houseValue"></span></p>
|
||||
<p>Homeowner Net Worth: <span id="homeownerNetWorth"></span></p>
|
||||
<p>Renter Net Worth: <span id="renterNetWorth"></span></p>
|
||||
<h4 id="comparisonResult"></h4>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Simple helper to update the text next to sliders
|
||||
function updateDisplay(spanId, val) {
|
||||
document.getElementById(spanId).innerText = val;
|
||||
}
|
||||
|
||||
function calculate() {
|
||||
// Collect the current slider/input values
|
||||
let data = {
|
||||
current_age: document.getElementById('currentAge').value,
|
||||
age_at_death: document.getElementById('ageAtDeath').value,
|
||||
monthly_salary: document.getElementById('monthlySalary').value,
|
||||
monthly_rent: document.getElementById('monthlyRent').value,
|
||||
home_cost: document.getElementById('homeCost').value,
|
||||
down_payment: document.getElementById('downPayment').value,
|
||||
monthly_expenses: document.getElementById('monthlyExpenses').value,
|
||||
investment_return: document.getElementById('investmentReturn').value
|
||||
};
|
||||
|
||||
// Send data to the server via POST /compute
|
||||
fetch('/compute', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(data)
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(result => {
|
||||
// Update the page with the returned results
|
||||
document.getElementById('renterInvestment').innerText = result.renter_investment_balance;
|
||||
document.getElementById('homeownerInvestment').innerText = result.homeowner_investment_balance;
|
||||
document.getElementById('houseValue').innerText = result.final_house_value;
|
||||
document.getElementById('homeownerNetWorth').innerText = result.homeowner_net_worth;
|
||||
document.getElementById('renterNetWorth').innerText = result.renter_net_worth;
|
||||
|
||||
// Compare difference
|
||||
let difference = result.difference;
|
||||
let comparison = "";
|
||||
if (difference > 0) {
|
||||
comparison = `Buying is ahead by $${Math.abs(difference).toLocaleString()}.`;
|
||||
// color it green
|
||||
document.getElementById('comparisonResult').style.color = 'green';
|
||||
} else if (difference < 0) {
|
||||
comparison = `Renting is ahead by $${Math.abs(difference).toLocaleString()}.`;
|
||||
// color it green
|
||||
document.getElementById('comparisonResult').style.color = 'green';
|
||||
} else {
|
||||
comparison = "Both scenarios come out exactly the same!";
|
||||
document.getElementById('comparisonResult').style.color = 'orange';
|
||||
}
|
||||
document.getElementById('comparisonResult').innerText = comparison;
|
||||
})
|
||||
.catch(err => {
|
||||
console.error(err);
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
164
templates/index.html
Normal file
164
templates/index.html
Normal file
@@ -0,0 +1,164 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Own vs Rent Analyzer</title>
|
||||
<style>
|
||||
body { font-family: Arial, sans-serif; margin: 20px; }
|
||||
.slider-container { margin-bottom: 15px; }
|
||||
label { display: inline-block; width: 250px; }
|
||||
input[type=range] { width: 300px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Own vs Rent Analyzer</h1>
|
||||
<div>
|
||||
<div class="slider-container">
|
||||
<label for="annual_income">Annual Income ($):</label>
|
||||
<input type="range" id="annual_income" min="30000" max="200000" step="1000" value="60000" oninput="updateValue('annual_income')">
|
||||
<span id="annual_income_val">60000</span>
|
||||
</div>
|
||||
<div class="slider-container">
|
||||
<label for="home_price">Home Price ($):</label>
|
||||
<input type="range" id="home_price" min="100000" max="1000000" step="10000" value="300000" oninput="updateValue('home_price')">
|
||||
<span id="home_price_val">300000</span>
|
||||
</div>
|
||||
<div class="slider-container">
|
||||
<label for="down_payment">Down Payment ($):</label>
|
||||
<input type="range" id="down_payment" min="10000" max="500000" step="5000" value="60000" oninput="updateValue('down_payment')">
|
||||
<span id="down_payment_val">60000</span>
|
||||
</div>
|
||||
<div class="slider-container">
|
||||
<label for="mortgage_rate">Mortgage Rate (%):</label>
|
||||
<input type="range" id="mortgage_rate" min="1" max="10" step="0.1" value="4" oninput="updateValue('mortgage_rate')">
|
||||
<span id="mortgage_rate_val">4</span>
|
||||
</div>
|
||||
<div class="slider-container">
|
||||
<label for="mortgage_term">Mortgage Term (years):</label>
|
||||
<input type="range" id="mortgage_term" min="10" max="40" step="1" value="30" oninput="updateValue('mortgage_term')">
|
||||
<span id="mortgage_term_val">30</span>
|
||||
</div>
|
||||
<div class="slider-container">
|
||||
<label for="property_tax_rate">Property Tax Rate (%):</label>
|
||||
<input type="range" id="property_tax_rate" min="0" max="5" step="0.1" value="1.2" oninput="updateValue('property_tax_rate')">
|
||||
<span id="property_tax_rate_val">1.2</span>
|
||||
</div>
|
||||
<div class="slider-container">
|
||||
<label for="homeowner_insurance">Homeowner Insurance ($/year):</label>
|
||||
<input type="range" id="homeowner_insurance" min="500" max="5000" step="100" value="1200" oninput="updateValue('homeowner_insurance')">
|
||||
<span id="homeowner_insurance_val">1200</span>
|
||||
</div>
|
||||
<div class="slider-container">
|
||||
<label for="maintenance_rate">Maintenance Rate (%):</label>
|
||||
<input type="range" id="maintenance_rate" min="0" max="5" step="0.1" value="1" oninput="updateValue('maintenance_rate')">
|
||||
<span id="maintenance_rate_val">1</span>
|
||||
</div>
|
||||
<div class="slider-container">
|
||||
<label for="rent">Rent ($/month):</label>
|
||||
<input type="range" id="rent" min="500" max="5000" step="50" value="1500" oninput="updateValue('rent')">
|
||||
<span id="rent_val">1500</span>
|
||||
</div>
|
||||
<div class="slider-container">
|
||||
<label for="rent_escalation_rate">Rent Escalation Rate (%):</label>
|
||||
<input type="range" id="rent_escalation_rate" min="0" max="10" step="0.1" value="3" oninput="updateValue('rent_escalation_rate')">
|
||||
<span id="rent_escalation_rate_val">3</span>
|
||||
</div>
|
||||
<div class="slider-container">
|
||||
<label for="home_appreciation">Home Appreciation Rate (%):</label>
|
||||
<input type="range" id="home_appreciation" min="0" max="10" step="0.1" value="3" oninput="updateValue('home_appreciation')">
|
||||
<span id="home_appreciation_val">3</span>
|
||||
</div>
|
||||
<div class="slider-container">
|
||||
<label for="investment_return">Investment Return (%):</label>
|
||||
<input type="range" id="investment_return" min="0" max="15" step="0.1" value="5" oninput="updateValue('investment_return')">
|
||||
<span id="investment_return_val">5</span>
|
||||
</div>
|
||||
<div class="slider-container">
|
||||
<label for="marginal_tax_rate">Marginal Tax Rate (%):</label>
|
||||
<input type="range" id="marginal_tax_rate" min="0" max="50" step="1" value="25" oninput="updateValue('marginal_tax_rate')">
|
||||
<span id="marginal_tax_rate_val">25</span>
|
||||
</div>
|
||||
<div class="slider-container">
|
||||
<label for="inflation_rate">Inflation Rate (%):</label>
|
||||
<input type="range" id="inflation_rate" min="0" max="10" step="0.1" value="2" oninput="updateValue('inflation_rate')">
|
||||
<span id="inflation_rate_val">2</span>
|
||||
</div>
|
||||
<div class="slider-container">
|
||||
<label for="start_age">Start Age:</label>
|
||||
<input type="range" id="start_age" min="18" max="70" step="1" value="30" oninput="updateValue('start_age')">
|
||||
<span id="start_age_val">30</span>
|
||||
</div>
|
||||
<div class="slider-container">
|
||||
<label for="end_age">End Age:</label>
|
||||
<input type="range" id="end_age" min="30" max="100" step="1" value="65" oninput="updateValue('end_age')">
|
||||
<span id="end_age_val">65</span>
|
||||
</div>
|
||||
<button onclick="runSimulation()">Run Simulation</button>
|
||||
</div>
|
||||
|
||||
<h2>Results</h2>
|
||||
<div id="results">
|
||||
<p id="renter_investment"></p>
|
||||
<p id="homeowner_investment"></p>
|
||||
<p id="final_house_value"></p>
|
||||
<p id="homeowner_net_worth"></p>
|
||||
<p id="renter_net_worth"></p>
|
||||
<p id="lifetime_income"></p>
|
||||
<p id="comparison"></p>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function updateValue(id) {
|
||||
var val = document.getElementById(id).value;
|
||||
document.getElementById(id + '_val').innerText = val;
|
||||
}
|
||||
|
||||
function runSimulation() {
|
||||
// Gather parameters from the sliders
|
||||
var params = {
|
||||
annual_income: parseFloat(document.getElementById('annual_income').value),
|
||||
home_price: parseFloat(document.getElementById('home_price').value),
|
||||
down_payment: parseFloat(document.getElementById('down_payment').value),
|
||||
mortgage_rate: parseFloat(document.getElementById('mortgage_rate').value) / 100,
|
||||
mortgage_term: parseFloat(document.getElementById('mortgage_term').value),
|
||||
property_tax_rate: parseFloat(document.getElementById('property_tax_rate').value) / 100,
|
||||
homeowner_insurance: parseFloat(document.getElementById('homeowner_insurance').value),
|
||||
maintenance_rate: parseFloat(document.getElementById('maintenance_rate').value) / 100,
|
||||
rent: parseFloat(document.getElementById('rent').value),
|
||||
rent_escalation_rate: parseFloat(document.getElementById('rent_escalation_rate').value) / 100,
|
||||
home_appreciation: parseFloat(document.getElementById('home_appreciation').value) / 100,
|
||||
investment_return: parseFloat(document.getElementById('investment_return').value) / 100,
|
||||
marginal_tax_rate: parseFloat(document.getElementById('marginal_tax_rate').value) / 100,
|
||||
inflation_rate: parseFloat(document.getElementById('inflation_rate').value) / 100,
|
||||
start_age: parseFloat(document.getElementById('start_age').value),
|
||||
end_age: parseFloat(document.getElementById('end_age').value),
|
||||
annual_salary_growth: 0.02, // fixed for now
|
||||
renters_insurance_annual: 240
|
||||
};
|
||||
|
||||
// Send the parameters to the backend /calculate endpoint via POST
|
||||
fetch('/calculate', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(params)
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
document.getElementById('renter_investment').innerText = "Renter's Final Investment Balance: $" + data.renter_final_investment.toFixed(2);
|
||||
document.getElementById('homeowner_investment').innerText = "Homeowner's Final Investment Balance: $" + data.homeowner_final_investment.toFixed(2);
|
||||
document.getElementById('final_house_value').innerText = "Final House Value: $" + data.final_house_value.toFixed(2);
|
||||
document.getElementById('homeowner_net_worth').innerText = "Homeowner Net Worth: $" + data.homeowner_net_worth.toFixed(2);
|
||||
document.getElementById('renter_net_worth').innerText = "Renter Net Worth: $" + data.renter_net_worth.toFixed(2);
|
||||
document.getElementById('lifetime_income').innerText = "Lifetime Income: $" + data.lifetime_income.toFixed(2);
|
||||
var comparison = data.homeowner_net_worth > data.renter_net_worth ?
|
||||
"Home ownership is better over the set duration." :
|
||||
"Renting is better over the set duration.";
|
||||
document.getElementById('comparison').innerText = comparison;
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Login</title>
|
||||
</head>
|
||||
<body>
|
||||
<h2>Login</h2>
|
||||
{% if error %}
|
||||
<p style="color: red;">{{ error }}</p>
|
||||
{% endif %}
|
||||
<form method="POST">
|
||||
<label>Username: <input type="text" name="username"></label><br><br>
|
||||
<label>Password: <input type="password" name="password"></label><br><br>
|
||||
<input type="submit" value="Login">
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user