Skip to content

Commit

Permalink
Adding Loan Calculator project
Browse files Browse the repository at this point in the history
  • Loading branch information
danfimov committed Aug 16, 2021
1 parent e43e755 commit 34b7887
Show file tree
Hide file tree
Showing 16 changed files with 1,261 additions and 0 deletions.
124 changes: 124 additions & 0 deletions Python Developer/Loan Calculator/Annuity payment/task-info.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
type: edu
custom_name: stage3
files:
- name: creditcalc/creditcalc.py
visible: true
text: |
loan_principal = 'Loan principal: 1000'
final_output = 'The loan has been repaid!'
first_month = 'Month 1: repaid 250'
second_month = 'Month 2: repaid 250'
third_month = 'Month 3: repaid 500'
# write your code here
learner_created: false
- name: tests.py
visible: false
text: |
from hstest.stage_test import StageTest
from hstest.test_case import TestCase
from hstest.check_result import CheckResult
import re
CheckResult.correct = lambda: CheckResult(True, '')
CheckResult.wrong = lambda feedback: CheckResult(False, feedback)
class LoanCalcTest(StageTest):
def generate(self):
return [
TestCase(
stdin='a\n1000000\n60\n10',
attach=21248,
),
TestCase(
stdin='a\n1000000\n8\n9.8',
attach=129638,
),
TestCase(
stdin='a\n3000000\n302\n11.2',
attach=29803,
),
TestCase(
stdin='n\n500000\n23000\n7.8',
attach=[2, 0],
),
TestCase(
stdin='n\n700000\n26000\n9.1',
attach=[2, 7],
),
TestCase(
stdin='p\n8721.8\n120\n5.6',
attach=(800000,),
),
TestCase(
stdin='p\n6898.02\n240\n3.4',
attach=(1200001,),
),
]
def check(self, reply, attach):
numbers = re.findall(r'[-+]?(\d*\.\d+|\d+)', reply)
if len(numbers) == 0:
return CheckResult.wrong(
'No numbers in the answer',
)
if isinstance(attach, tuple):
for i in numbers:
if abs(attach[0] - float(i)) < 2:
return CheckResult.correct()
output = 'Numbers in your answer: ' + ' '.join(numbers)
output += 'But correct principal is {0}'.format(attach)
return CheckResult.wrong(output)
if isinstance(attach, list):
# to exclude answers like 'it takes 2.01 years'
# but 'it takes 2.0 years' let it be OK.
epsilon = 0.00001
numbers = [
int(float(x)) for x in numbers
if abs(int(float(x)) - float(x)) < epsilon
]
if attach[1] == 0:
if 'year' in reply.lower() and attach[0] in numbers:
return CheckResult.correct()
output = 'Correct result: {0} years, but you output "{1}"'
return CheckResult.wrong(
output.format(attach[0], reply),
)
else:
if attach[0] in numbers and 'year' in reply.lower():
if attach[1] in numbers and 'month' in reply.lower():
return CheckResult.correct()
output = (
'Correct result: {0} years {1} months, '
'but you output "{2}"'
)
return CheckResult.wrong(
output.format(attach[0], attach[1], reply),
)
if str(attach) not in reply.lower():
output = (
'Correct annuity payment is {0} but you output numbers: {1}'
)
figures = ' '.join(numbers)
return CheckResult.wrong(
output.format(attach, figures),
)
return CheckResult.correct()
if __name__ == '__main__':
LoanCalcTest('creditcalc.creditcalc').run_tests()
learner_created: false
feedback_link: https://hyperskill.org/projects/90/stages/502/implement#comment
status: Solved
feedback:
message: Congratulations!
time: Mon, 16 Aug 2021 08:47:35 UTC
record: 3
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
id: 8004
update_date: Thu, 12 Aug 2021 19:48:31 UTC
117 changes: 117 additions & 0 deletions Python Developer/Loan Calculator/Annuity payment/task.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
<h2 style="text-align: center;">Description</h2>

<p>Let's compute all the parameters of the loan. There are at least two kinds of loan: those with annuity payment and those with differentiated payment. In this stage, you are going to calculate only the annuity payment which is fixed during the whole loan term.</p>

<p>Here is the formula:</p>

<p style="text-align: center;"><span class="math-tex">\(A_{ordinary\_annuity} = P * \dfrac{i * (1+i)^n}{(1+i)^n-1}\)</span></p>

<p>Where:</p>

<p><span class="math-tex">\(A\)</span> = annuity payment;</p>

<p><span class="math-tex">\(P\)</span> = loan principal;</p>

<p><span class="math-tex">\(i\)</span> = nominal (monthly) interest rate. Usually, it’s 1/12 of the annual interest rate, and usually, it’s a floating value, not a percentage. For example, if your annual interest rate = 12%, then i = 0.01;</p>

<p><span class="math-tex">\(n\)</span> = number of payments. This is usually the number of months in which repayments will be made.</p>

<p>You are interested in four values: the number of monthly payments required to repay the loan, the monthly payment amount, the loan principal, and the loan interest. Each of these values can be calculated if others are known:</p>

<p><strong>Loan principal:</strong></p>

<p><span class="math-tex">\(P = \dfrac{A}{\left( \dfrac{i * (1+i)^n}{(1+i)^n-1} \right)}\)</span></p>

<p><strong>The number of payments:</strong></p>

<p><strong><span class="math-tex">\(n = \log_{1+i} \left( \dfrac{A}{A - i*P} \right)\)</span></strong></p>

<h2 style="text-align: center;">Objectives</h2>

<p>In this stage, you should add new behavior to the calculator:</p>

<ol>
<li>First, you should ask the user which parameter they want to calculate. The calculator should be able to calculate the number of monthly payments, the monthly payment amount, and the loan principal.</li>
<li>Then, you need to ask them to input the remaining values.</li>
<li>Finally, compute and output the value that they wanted.</li>
</ol>

<p><div class="alert alert-warning">Note that the user inputs the interest rate as a percentage, for example, 11.7, so you should divide this value by 100 to use it in the formula above.</div></p>

<p>Please be careful converting "<strong>X months</strong>" to "<strong>Y years and Z months</strong>". Avoid writing "0 years and 11 months" (output "11 months" instead) and "1 years and 0 months" (output "1 year" instead).</p>

<p>Note that in this stage, you have to ask the user to input parameters in a specific order which is provided below. Simply skip the value the user wants to calculate:</p>

<ul>
<li>The first is the loan principal. </li>
<li>The second is the monthly payment. </li>
<li>The next is the number of monthly payments.</li>
<li>The last is the loan interest.</li>
</ul>

<h2 style="text-align: center;">Examples</h2>

<p>The greater-than symbol followed by a space (<code class="java">&gt; </code>) represents the user input. Note that this is not part of the input.</p>

<p><strong>Example 1</strong></p>

<pre><code class="language-no-highlight">What do you want to calculate?
type "n" for number of monthly payments,
type "a" for annuity monthly payment amount,
type "p" for loan principal:
&gt; n
Enter the loan principal:
&gt; 1000000
Enter the monthly payment:
&gt; 15000
Enter the loan interest:
&gt; 10
It will take 8 years and 2 months to repay this loan!</code></pre>

<p>Let’s take a closer look at <strong>Example 1</strong>.</p>

<p>You know the loan principal, the loan interest and want to calculate the number of monthly payments. What do you do?</p>

<p>1) You need to know the nominal interest rate. It is calculated like this:</p>

<p><span class="math-tex">\(i = \dfrac{10\%}{12 * 100\%} = 0.008333...\)</span></p>

<p>2) Now you can calculate the number of months:</p>

<p><span class="math-tex">\(n = \log_{1 + 0.008333...} \left( \dfrac{15000}{15000-0.008333... * 1000000} \right) = 97.71...\)</span></p>

<p>3) You need an integer number, so let’s round it up. Notice that the user will pay the same amount every month for 97 months, and in the 98th month the user will pay<em> 0.71...</em> of the monthly payment. So, there are 98 months to pay.</p>

<p><span class="math-tex">\(n = 98\)</span></p>

<p>4) Finally, you need to convert “98 months” to “8 years and 2 months” so that it is more readable and understandable for the user.</p>

<p><strong>Example 2</strong></p>

<pre><code class="language-no-highlight">What do you want to calculate?
type "n" for number of monthly payments,
type "a" for annuity monthly payment amount,
type "p" for loan principal:
&gt; a
Enter the loan principal:
&gt; 1000000
Enter the number of periods:
&gt; 60
Enter the loan interest:
&gt; 10
Your monthly payment = 21248!</code></pre>

<p><strong>Example 3</strong></p>

<pre><code class="language-no-highlight">What do you want to calculate?
type "n" for number of monthly payments,
type "a" for annuity monthly payment amount,
type "p" for loan principal:
&gt; p
Enter the annuity payment:
&gt; 8721.8
Enter the number of periods:
&gt; 120
Enter the loan interest:
&gt; 5.6
Your loan principal = 800000!</code></pre>
59 changes: 59 additions & 0 deletions Python Developer/Loan Calculator/Beginning/task-info.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
type: edu
custom_name: stage1
files:
- name: tests.py
visible: false
text: |
from hstest.stage_test import StageTest
from hstest.test_case import TestCase
from hstest.check_result import CheckResult
CheckResult.correct = lambda: CheckResult(True, '')
CheckResult.wrong = lambda feedback: CheckResult(False, feedback)
class LoanCalcTest(StageTest):
def generate(self):
return [TestCase()]
def check(self, reply, attach):
print_strs = [
'Loan principal: 1000',
'Month 1: repaid 250',
'Month 2: repaid 250',
'Month 3: repaid 500',
'The loan has been repaid!',
]
for print_str in print_strs:
if print_str not in reply:
return CheckResult.wrong(
'You forgot to output string "{0}"'.format(print_str),
)
if not '\n'.join(print_strs) in reply:
return CheckResult.wrong('You output strings in the wrong order')
return CheckResult.correct()
if __name__ == '__main__':
LoanCalcTest('creditcalc.creditcalc').run_tests()
learner_created: false
- name: creditcalc/creditcalc.py
visible: true
text: |
loan_principal = 'Loan principal: 1000'
final_output = 'The loan has been repaid!'
first_month = 'Month 1: repaid 250'
second_month = 'Month 2: repaid 250'
third_month = 'Month 3: repaid 500'
# write your code here
learner_created: false
feedback_link: https://hyperskill.org/projects/90/stages/500/implement#comment
status: Solved
feedback:
message: Congratulations!
time: Sun, 15 Aug 2021 21:14:52 UTC
record: 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
id: 8002
update_date: Tue, 15 Jun 2021 18:40:08 UTC
19 changes: 19 additions & 0 deletions Python Developer/Loan Calculator/Beginning/task.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<h2 style="text-align: center;">Description</h2>

<p>Let's think about what a loan calculator should be able to do. In general, it takes several parameters like a loan principal and interest, calculates the values the user wants to know (for example, monthly payment or overpayment), and outputs them to the user.</p>

<p>Not familiar with these concepts? Don't worry, we will explain them to you in simple terms. The principal is the original amount of money you borrow. The interest is a charge for borrowing that money, usually calculated as a percentage of the principal amount.</p>

<h2 style="text-align: center;">Objectives</h2>

<p>Let's start by imitating this behavior. There are some prepared variables in the source code: these are text messages that our loan calculator can output. In this stage, all you need to do is output them in the right order.</p>

<h2 style="text-align: center;">Example</h2>

<p>Output:</p>

<pre><code class="language-no-highlight">Loan principal: 1000
Month 1: repaid 250
Month 2: repaid 250
Month 3: repaid 500
The loan has been repaid!</code></pre>
Loading

0 comments on commit 34b7887

Please sign in to comment.