-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcode.html
More file actions
448 lines (400 loc) · 18.7 KB
/
Copy pathcode.html
File metadata and controls
448 lines (400 loc) · 18.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
<!DOCTYPE html>
<html lang="en" class="h-100">
<head>
<title>LOAN SHARK: A CODING EXERCISE</title>
<!-- Required meta tags -->
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>
<!-- Bootstrap CSS -->
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC"
crossorigin="anonymous"
/>
<script
src="https://kit.fontawesome.com/5db21ba9c6.js"
crossorigin="anonymous"
></script>
<link href="/css/site.css" rel="stylesheet" />
<link rel="icon" type="image/png" href="/img/favicon.ico" />
<link href="css/prism.css" rel="stylesheet" />
</head>
<body class="d-flex flex-column h-100">
<!-- ==== Nav Section ==== -->
<nav class="navbar navbar-expand-md navbar-dark fixed-top">
<div class="container-fluid">
<a class="navbar-brand navAppFont" href="#"
><img
src="/img/LS-ICON.png"
class="d-inline-block align-text-top"
alt="LOAN SHARK Logo"
width="38"
height="38"
/>
LOAN SHARK</a
>
<button
class="navbar-toggler"
type="button"
data-bs-toggle="collapse"
data-bs-target="#navbarCollapse"
aria-controls="navbarCollapse"
aria-expanded="false"
aria-label="Toggle navigation"
>
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarCollapse">
<ul class="navbar-nav me-auto mb-2 mb-md-0">
<li class="nav-item">
<a class="nav-link" href="index.html">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/app.html">The App</a>
</li>
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="/code.html"
>The Code</a
>
</li>
<li class="nav-item">
<a
class="nav-link"
target="_blank"
href="https://github.com/apnihiser/Loan-Shark"
>Git Repo</a
>
</li>
<!-- <li class="nav-item">
<a
class="nav-link"
target="_blank"
href="https://anihiser-portfolio.netlify.app/"
>About</a
>
</li> -->
</ul>
</div>
</div>
</nav>
<!-- ==== Main Section ==== -->
<main class="flex-shrink-0">
<div class="container py-5 px-5 mt-5">
<h2 class="border-1 border-bottom border-dark">
The Code for LOAN SHARK
</h2>
<div class="row row-cols-1 row-cols-lg-2">
<div class="col-lg-8">
<!-- CODE HERE -->
<pre class="line-numbers"><code class="language-javascript">
//Controller function
//gather data from webform
function getValues() {
//Define a new loan object
loan = {};
loan.payment = 0.00;
loan.totalInterest = 0.00;
loan.totalCost = 0.00;
loan.rate = 0.00;
loan.amount = 0.00;
loan.term = 0.00;
loan.payments = [];
//Grab data from the Form
loan.amount = parseInt(document.getElementById("inputLoanAmount").value);
loan.term = parseInt(document.getElementById("inputTermLength").value);
loan.rate = parseInt(document.getElementById("inputInterestRate").value);
//Calculate the loan and get payments
newLoan = getPayments(loan);
//Send newLoan object to be displayed in HTML
displayValues(newLoan);
}
function getPayments(loan) {
//Calculate Monthly Payment
loan.payment = calcPayment(loan.amount, loan.rate, loan.term);
//For loop from month 1 to the term to calculate a payment schedule
let balance = loan.amount;
let totalInterest = 0.00;
let monthlyInterest = 0.00;
let monthlyPrincipal = 0.0;
let monthlyRate = calcMonthlyRate(loan.rate)
for (let month = 1; month <= loan.term; month++) {
//Logic based on requirements provided by Business Unit
monthlyInterest = calcMonthlyInterest(balance, monthlyRate);
totalInterest += monthlyInterest;
monthlyPrincipal = loan.payment - monthlyInterest;
balance -= monthlyPrincipal;
//Define loan Payment object and shape data per month / loop.
loanPayment = {};
loanPayment.month = month;
loanPayment.payment = loan.payment;
loanPayment.monthlyPrincipal = monthlyPrincipal;
loanPayment.monthlyInterest = monthlyInterest;
loanPayment.totalInterest = totalInterest;
loanPayment.balance = balance;
//Push payments into the loan object
loan.payments.push(loanPayment);
}
loan.totalInterest = totalInterest;
loan.totalCost = loan.amount + totalInterest;
//Return the loan to the view
return loan;
}
//Calculate monthly payment using mortgage formula
function calcPayment(amount, rate, term) {
let monthlyRate = calcMonthlyRate(rate);
payment = (amount * monthlyRate) / (1 - Math.pow(1 + monthlyRate, -term));
return payment;
}
//convert annual rate into monthly
function calcMonthlyRate(rate) {
return rate / 1200;
}
//Calculate monthly interest
function calcMonthlyInterest(balance, monthlyRate) {
return balance * monthlyRate;
}
//Use information from loan object to append to HTML Table Body
function displayValues(loan) {
//Use this to format currency
const formatter = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
minimumFractionDigits: 2
})
//get the table body element from the page
let tableBody = document.getElementById("results");
//get the template row
let templateRow = document.getElementById("lsTemplate");
//clear tablebody
tableBody.innerHTML = "";
//Push results to the summary section of the application page
document.getElementById("payment").innerHTML = formatter.format(loan.payment);
document.getElementById("principal").innerHTML = formatter.format(loan.amount);
document.getElementById("interest").innerHTML = formatter.format(loan.totalInterest);
document.getElementById("cost").innerHTML = formatter.format(loan.totalCost);
//Loop to append each payment to HTML table
loan.payments.forEach (payment => {
//Each loop grab the template and import the table row.
let tableRow = document.importNode(templateRow.content, true);
//grab just the tds and put them into an array
let rowCols = tableRow.querySelectorAll("td");
//fill template array with monthly payment schedule
rowCols[0].textContent = payment.month;
rowCols[1].textContent = formatter.format(payment.payment);
rowCols[2].textContent = formatter.format(payment.monthlyPrincipal);
rowCols[3].textContent = formatter.format(payment.monthlyInterest);
rowCols[4].textContent = formatter.format(payment.totalInterest);
rowCols[5].textContent = formatter.format(payment.balance);
//Append to Table body
tableBody.appendChild(tableRow);
});
}
</code>
</pre>
</div>
<!-- CODE DESCRIPTION HERE -->
<div class="col-lg-4">
<h4>APP ANALYSIS</h4>
<br />
<h5>SUMMARY</h5>
<p class="lead">
Loan Shark is an application created to assist the loanee in
understanding their payment schedule. This application also
provides a handy summary of the loan to get a high level snapshot
of their overall costs. Please see the the description below. Also
the code will be displayed to the left with additional notes to
provide context.
</p>
<p class="lead">
Conceptully you can approach the design of this application in a 3
teir architecture.
</p>
<ul>
<li class="lead">Controller Function</li>
<li class="lead">Logic and Helper Functions</li>
<li class="lead">Display Function</li>
</ul>
<h5>CONTROLLER FUNCTION</h5>
<p class="lead">
The important element behind this application is the data
modeling. Passing information between functions can get messy
without a solid structural element to organize the data. With that
being the case we will be creating a loan object. This object will
contain important elements like the interest, principal, payment
schedule and more. The display page will feature a summary and a
detailed table which will display the properties of this object.
The main function of the controller function is capturing the
requested loan parameters and to create a new loan object and pass
this data between the logic and display functions.
</p>
<h5>LOGICAL SYSTEM</h5>
<p class="lead">
The logical system will receive a loan object from the controller
function. This data has been modeled but will need to be described
with more detail as all of the business logic has not been
implemented. That will be the main function of the logical system.
The logical system with this application can be broken down into
these functions:
</p>
<ul>
<li class="lead">
<strong class="fst-italic">getPayments()</strong> : Receives a
loan object from the controller function. With assistance of 3
helper functions it will fully describe the loan object. One
notable element of this function is the creation of a new object
named loanPayment. This will describe a single monthly payment
which will be pushed into the
<strong class="fst-italic">loan.payments</strong> array during a
loop iterating over the loan's term length.
</li>
<ol>
<li class="lead">
<strong class="fst-italic">calcPayment()</strong> : Calculate
monthly payment based on mortgage formula.
</li>
<li class="lead">
<strong class="fst-italic">calcMonthlyRate()</strong> :
Convert APR to monthly rate.
</li>
<li class="lead">
<strong class="fst-italic">calcMonthlyInterest()</strong> :
Dynamically determine interest based on previous month.
</li>
</ol>
</ul>
<p class="lead">
Once all of the data has been detailed and the loan object has
been updated. This will be send back to the controller function in
the form of a newLoan object.
</p>
<h5>DISPLAY FUNCTION</h5>
<p class="lead">
To append this data to the HTML page we will go through a
mechanism described in several steps:
</p>
<ol class="lead">
<li>Capture the table body element from the HTML page.</li>
<li>Capture the empty template marked up on the HTML page.</li>
<li>Per forEach Loop:</li>
<ol type="A">
<li>Import a table row from the template in step 2.</li>
<li>
Create an array that will contains all 6 table data cells
inside the table row in the previous step.
</li>
<li>
Push all 6
<strong class="fst-italic">loan.payment</strong> properties
into the array.
</li>
<li>
Append the array as a child to the table targeted in step 1.
</li>
</ol>
</ol>
<p class="lead">
Just to back up a bit and hit a couple other operations before the
forEach loop. Since these are financial figures we are working
with there is formatting that needs to be accounted for. The
easiest way to format these is to use the
<strong class="fst-italic">Intl.NumberFormat</strong> Javascript
built in. This oeprations is wrapped around all figures so they
are formatted correctly. Also the summary section of the display
page does include a summarization of the loan which highlights the
most important features of the loan. All of this is written before
the forEach loop by simply utilizing the
<strong class="fst-italic">.innerHTML = Javascript</strong>
function.
</p>
<h5>CONCLUSION</h5>
<p class="lead">
Loan Shark is the perfect usecase to illustrate the powerful
nature of objects in programming and how they can take a messy
pile of functions and data and create beautifully organized code
which is easy to follow, update, and troubleshoot. Since one
object is being passed from function to function it is easy to
keep track of all properties and massage them exactly how the need
requires.
</p>
</div>
</div>
</div>
</main>
<!-- ==== Footer Section ==== -->
<footer class="footer mt-auto py-3 sticky-footer">
<div class="container-fluid">
<div class="row row-cols-1 row-cols-lg-3">
<div
class="col order-last order-lg-first text-light d-flex align-items-end justify-content-start gy-2"
>
<div>
<span class="text-muted">©2021</span> Adam Nihiser |
anihiser@gmail.com
</div>
</div>
<div
class="col d-flex align-items-end justify-content-start justify-content-lg-center gy-3"
>
<img
src="/img/ANihiser_NewWordmark.png"
alt="Adam Nihiser Logo"
height="32"
/>
</div>
<div
class="col d-flex align-items-end justify-content-start justify-content-lg-end gy-3"
>
<div class="row">
<div class="col social">
<a href="https://www.linkedin.com/in/anihiser/" target="_blank"
><i class="fab fa-linkedin fa-2x"></i
></a>
</div>
<div class="col social">
<a href="https://github.com/apnihiser" target="_blank"
><i class="fab fa-github fa-2x"></i
></a>
</div>
<div class="col social">
<a href="https://twitter.com/That_APN_Guy" target="_blank"
><i class="fab fa-twitter fa-2x"></i
></a>
</div>
<div class="col social">
<a
href="https://www.youtube.com/channel/UCZl9auJaZm4S3sOHCBcxgEQ"
target="_blank"
><i class="fab fa-youtube fa-2x"></i
></a>
</div>
</div>
</div>
</div>
</div>
</footer>
<!-- Bootstrap JS -->
<script
src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.2/dist/umd/popper.min.js"
integrity="sha384-IQsoLXl5PILFhosVNubq5LC7Qb9DXgDA9i+tQ8Zj3iwWAwPtgFTxbJ8NT4GN1R8p"
crossorigin="anonymous"
></script>
<script
src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.min.js"
integrity="sha384-cVKIPhGWiC2Al4u+LWgxfKTRIcfu0JTxR+EQDz/bgldoEyl4H0zUF0QKbrJ0EcQF"
crossorigin="anonymous"
></script>
<script src="js/prism.js"></script>
<script>
Prism.plugins.NormalizeWhitespace.setDefaults({
"remove-trailing": true,
"remove-indent": true,
"left-trim": true,
"right-trim": true,
});
</script>
</body>
</html>