Project: Mortgage Calculator Pt 2
Let’s go back to our Mortgage calculator and implement some basic error handling
- Update our Principal Label to suggest a range of money available to borrow being between
$1K - $1M
- If the user enters anything below or over the range a message is returned stating
Enter a number between 1,000 and 1,000,000
and the Principal input is shown.
- If the user enters anything below or over the range a message is returned stating
- The Annual Interest Rate should be updated to only accept a range that is
>0 and < 30
- If the user enters an invalid number the terminal prints
Enter a value greater tan 0 and less than or equal to 30.
and the Annual interest rate input is shown.
- If the user enters an invalid number the terminal prints
- The Period (Years) should be between
1 and 30
- If the user enters an invalid number the terminal prints
Enter a value between 1 and 30
and the Annual interest rate input is shown.
- If the user enters an invalid number the terminal prints
- Finally our monthly payments are returned.
Formula for calculating mortgage payments
Section titled “Formula for calculating mortgage payments”A reminder on the formula for calculating mortgage payments:
m = Mortgage p = Principal r = Monthly interest rate (r / 100)/12 n = Number of payments (as it’s monthly over 30 years number of months in 30 years.) 30 * 12
$M = P \times \frac{r(1 + r)^n}{(1 + r)^n - 1}$
Math has the pow method Math.pow(a, b)
where it takes the value of one and provides a power of to the second one.
Code I wrote for the project
Section titled “Code I wrote for the project”import java.text.NumberFormat;import java.util.Scanner;
public class MortgageCalculator { public static void main(String[] args) { final byte MONTHS_IN_YEAR = 12; final byte PERCENT = 100; Scanner scanner = new Scanner(System.in);
int principal; while(true){ System.out.print("What is your principal loan amount: "); principal = scanner.nextInt(); if (principal > 1000000 || principal < 1000){ System.out.println("Enter a number between 1,000 and 1,000,000"); } else { break; } }
float annualInterestRate; while (true){ System.out.print("What is your annual interest rate: "); // Interest rates are usually small numbers so float should be sufficient instead of double annualInterestRate = scanner.nextFloat(); if (annualInterestRate <= 0 || annualInterestRate > 30){ System.out.println("Enter a value greater than 0 and less than or equal to 30"); } else{ break; } }
float monthlyInterestRate = (annualInterestRate / PERCENT) / MONTHS_IN_YEAR; byte yearsLoaned; while(true){ System.out.print("How many years is the loan: "); yearsLoaned = scanner.nextByte(); if(yearsLoaned < 1 || yearsLoaned > 30){ System.out.println("Enter a value between 1 and 30"); } else { break; } }
int numberOfPayments = yearsLoaned * 12;
final int P = principal; final float R = monthlyInterestRate; final int N = numberOfPayments; final double M = P * (R*Math.pow((1+R),N))/(Math.pow((1+R),N)-1); NumberFormat currency = NumberFormat.getCurrencyInstance();
final String RESULT = currency.format(M); System.out.println(RESULT); }
}
My Notes and Takeaways
Section titled “My Notes and Takeaways”- Scoped variables needed to be refactored to be accessed outside while loops.
- Each scope error handler needed it’s own while loop
- It was important to be verbose in our bounds or else unexpected errors occurred.
Code Review and Refactoring
Section titled “Code Review and Refactoring”The code review with Mosh was aligned to my code structure and reaffirmed our scoped variables approach. The key learning I took from Mosh’s example was to group our scoped variables at the top of our main code block (particularly if they are used multiple times to make it easier to read for reviewers).
Updated Code With Grouped Variables
Section titled “Updated Code With Grouped Variables”import java.text.NumberFormat;import java.util.Scanner;
public class MortgageCalculator { public static void main(String[] args) { final byte MONTHS_IN_YEAR = 12; final byte PERCENT = 100;
int principal; float annualInterestRate; byte yearsLoaned;
Scanner scanner = new Scanner(System.in);
while(true){ System.out.print("What is your principal loan amount: "); principal = scanner.nextInt(); if (principal > 1000000 || principal < 1000){ System.out.println("Enter a number between 1,000 and 1,000,000"); } else { break; } }
while (true){ System.out.print("What is your annual interest rate: "); annualInterestRate = scanner.nextFloat(); if (annualInterestRate <= 0 || annualInterestRate > 30){ System.out.println("Enter a value greater than 0 and less than or equal to 30"); } else{ break; } }
while(true){ System.out.print("How many years is the loan: "); yearsLoaned = scanner.nextByte(); if(yearsLoaned < 1 || yearsLoaned > 30){ System.out.println("Enter a value between 1 and 30"); } else { break; } }
int numberOfPayments = yearsLoaned * 12; float monthlyInterestRate = (annualInterestRate / PERCENT) / MONTHS_IN_YEAR;
final int P = principal; final float R = monthlyInterestRate; final int N = numberOfPayments; final double M = P * (R*Math.pow((1+R),N))/(Math.pow((1+R),N)-1);
NumberFormat currency = NumberFormat.getCurrencyInstance(); final String RESULT = currency.format(M); System.out.println(RESULT); }}