|
1 | 1 | import pathlib |
2 | 2 | from abc import ABC, abstractmethod |
3 | | -from datetime import datetime |
4 | 3 |
|
5 | 4 | import pytest |
6 | 5 | from numpy import average |
@@ -91,9 +90,6 @@ def test_child_eye_color(mother_eye_color, father_eye_color, function_to_test): |
91 | 90 | def reference_banking_system( |
92 | 91 | tax_rate: float, |
93 | 92 | interest_rate: float, |
94 | | - gross_salary: int, |
95 | | - savings_precentage: float, |
96 | | - years_passed: int, |
97 | 93 | ) -> float: |
98 | 94 | class Account(ABC): |
99 | 95 | def __init__(self, account_number): |
@@ -129,49 +125,103 @@ class SavingsAccount(Account): |
129 | 125 | def __init__(self, account_number, interest_rate): |
130 | 126 | super().__init__(account_number) |
131 | 127 | self.interest_rate = interest_rate |
132 | | - self.creation_year = datetime.now().year |
133 | 128 |
|
134 | 129 | def credit(self, amount): |
135 | 130 | self.balance += amount |
136 | 131 |
|
137 | | - def get_balance(self, years_passed): |
138 | | - interest = self.balance * self.interest_rate * years_passed |
139 | | - return self.balance + interest |
140 | | - |
141 | | - salary_account = SalaryAccount("SAL-001", tax_rate) |
142 | | - savings_account = SavingsAccount("SAV-001", interest_rate) |
143 | | - |
144 | | - salary_account.credit(gross_salary) |
| 132 | + def get_balance(self): |
| 133 | + return self.balance + self.balance * self.interest_rate |
145 | 134 |
|
146 | | - amount_to_transfer = salary_account.get_balance() * savings_precentage |
| 135 | + return [ |
| 136 | + SalaryAccount("SAL-001", tax_rate), |
| 137 | + SavingsAccount("SAV-001", interest_rate), |
| 138 | + ] |
147 | 139 |
|
148 | | - salary_account.debit(amount_to_transfer) |
149 | | - savings_account.credit(amount_to_transfer) |
150 | 140 |
|
151 | | - return savings_account.get_balance(years_passed) |
| 141 | +def validate_banking_system(solution_result): |
| 142 | + assert isinstance(solution_result, list), "Solution must return a list." |
| 143 | + assert len(solution_result) == 2, "The list must contain exactly two elements." |
| 144 | + assert all( |
| 145 | + isinstance(item, object) and type(item).__module__ != "builtins" |
| 146 | + for item in solution_result |
| 147 | + ), "Both elements in the list must be instances of custom classes." |
| 148 | + assert all( |
| 149 | + "Account" in [base.__name__ for base in type(item).__bases__] |
| 150 | + for item in solution_result |
| 151 | + ), "Both elements in the list must inherit from a class named 'Account'." |
| 152 | + assert type(solution_result[0]).__name__ == "SalaryAccount", ( |
| 153 | + "The 1st class should be an instance of 'SalaryAccount'." |
| 154 | + ) |
| 155 | + assert type(solution_result[1]).__name__ == "SavingsAccount", ( |
| 156 | + "The 2nd class should be an instance of 'SavingsAccount'." |
| 157 | + ) |
| 158 | + # Check the class attributes: SalaryAccount |
| 159 | + try: |
| 160 | + attrs = list(vars(solution_result[0])) |
| 161 | + except TypeError: |
| 162 | + raise SubAssertionError from None |
| 163 | + assert len(attrs) == 3, "The class 'SalaryAccount' should have 3 attributes." |
| 164 | + assert "account_number" in attrs, ( |
| 165 | + "The class 'SalaryAccount' should have an attribute called 'account_number'." |
| 166 | + ) |
| 167 | + assert "balance" in attrs, ( |
| 168 | + "The class 'SalaryAccount' should have an attribute called 'balance'." |
| 169 | + ) |
| 170 | + assert "tax_rate" in attrs, ( |
| 171 | + "The class 'SalaryAccount' should have an attribute called 'tax_rate'." |
| 172 | + ) |
| 173 | + # Check the class attributes: SavingsAccount |
| 174 | + try: |
| 175 | + attrs = list(vars(solution_result[1])) |
| 176 | + except TypeError: |
| 177 | + raise SubAssertionError from None |
| 178 | + assert len(attrs) == 3, "The class 'SavingsAccount' should have 3 attributes." |
| 179 | + assert "account_number" in attrs, ( |
| 180 | + "The class 'SavingsAccount' should have an attribute called 'account_number'." |
| 181 | + ) |
| 182 | + assert "balance" in attrs, ( |
| 183 | + "The class 'SavingsAccount' should have an attribute called 'balance'." |
| 184 | + ) |
| 185 | + assert "interest_rate" in attrs, ( |
| 186 | + "The class 'SavingsAccount' should have an attribute called 'interest_rate'." |
| 187 | + ) |
| 188 | + # Check that each class has the required methods |
| 189 | + required_methods = {"credit", "get_balance"} |
| 190 | + for item in solution_result: |
| 191 | + class_methods = { |
| 192 | + method for method in dir(item) if callable(getattr(item, method)) |
| 193 | + } |
| 194 | + assert required_methods.issubset(class_methods), ( |
| 195 | + f"The class '{type(item).__name__}' must have the methods: {', '.join(required_methods)}." |
| 196 | + ) |
152 | 197 |
|
153 | 198 |
|
154 | 199 | @pytest.mark.parametrize( |
155 | | - "tax_rate, interest_rate, gross_salary, savings_precentage, years_passed", |
| 200 | + "tax_rate, interest_rate", |
156 | 201 | [ |
157 | | - (0.20, 0.05, 10000, 0.3, 2), |
158 | | - (0.18, 0.04, 9300, 0.15, 3), |
159 | | - (0.13, 0.07, 8500, 0.18, 4), |
| 202 | + (0.20, 0.05), |
| 203 | + (0.18, 0.04), |
160 | 204 | ], |
161 | 205 | ) |
162 | 206 | def test_banking_system( |
163 | 207 | tax_rate, |
164 | 208 | interest_rate, |
165 | | - gross_salary, |
166 | | - savings_precentage, |
167 | | - years_passed, |
168 | 209 | function_to_test, |
169 | 210 | ): |
170 | | - assert function_to_test( |
171 | | - tax_rate, interest_rate, gross_salary, savings_precentage, years_passed |
172 | | - ) == reference_banking_system( |
173 | | - tax_rate, interest_rate, gross_salary, savings_precentage, years_passed |
174 | | - ) |
| 211 | + solution_result = function_to_test(tax_rate, interest_rate) |
| 212 | + reference_result = reference_banking_system(tax_rate, interest_rate) |
| 213 | + |
| 214 | + validate_banking_system(solution_result) |
| 215 | + |
| 216 | + amount = 10000 |
| 217 | + # test SalaryAccount functions |
| 218 | + solution_result[0].credit(amount) |
| 219 | + reference_result[0].credit(amount) |
| 220 | + assert solution_result[0].get_balance() == reference_result[0].get_balance() |
| 221 | + # test SavingsAccount functions |
| 222 | + solution_result[1].credit(amount) |
| 223 | + reference_result[1].credit(amount) |
| 224 | + assert solution_result[1].get_balance() == reference_result[1].get_balance() |
175 | 225 |
|
176 | 226 |
|
177 | 227 | # |
@@ -255,7 +305,7 @@ def test_store_inventory(function_to_test): |
255 | 305 |
|
256 | 306 |
|
257 | 307 | # |
258 | | -# Exercise 3: Music Streaming Service |
| 308 | +# Exercise 4: Music Streaming Service |
259 | 309 | # |
260 | 310 |
|
261 | 311 |
|
|
0 commit comments